当前位置: 首页 > 知识库问答 >
问题:

为什么只有static_cast能够返回请求类型的新对象?

胡翔
2023-03-14

在static_cast、dynamic_cast、reinterpret_cast和const_cast中,只有static_cast能够返回所需类型的对象,而另一种类型只能返回表示的指针或引用。为什么会这样?

例子:

int y = 3;
double z = reinterpret_cast<double> (y);//error
double z = reinterpret_cast<double&> (y);//ok
double z = static_cast<double> (y);//but this is ok!!!

const int y = 3;
int z = const_cast<int> (y);//error
int z = const_cast<int&> (y);//ok

对于dynamic_cast:

using namespace std;

class Gun
{
public:
    virtual void shoot(){
        cout << "BANG!\n";
    }
};

class MachineGun : public Gun{
public:
    void shoot() override{
        cout <<"3X-BANG\n";
    }
};

int main()
{
    Gun gun;
    MachineGun tt;
    Gun* gunp = &gun;
    Gun* gunp1 = &tt;

    Gun* newGun = dynamic_cast<Gun*>(gunp1);//ok
    Gun newGun1 = dynamic_cast<Gun>(tt);//error
}

共有3个答案

潘灵均
2023-03-14

也许一个简短(容易记住)的答案是< code>static_cast可以接受没有引用(和指针)的类型,因为它是唯一可以调用目标类型的构造函数的类型转换。

如果我错了,请纠正我。

潘星阑
2023-03-14

我试图根据例子来解释,作为对其他解释演员性质的答案的补充。

int y = 3;
double z = reinterpret_cast<double> (y);//error

这不是 11 个允许的具有reinterpret_cast的演员之一。此外,std::bit_cast不能在大多数平台上投射它,因为int通常没有足够的位进行双倍。所以不确定你想要实现什么。

double z = reinterpret_cast<double&> (y);//ok

这存在于有效的< code>reinterpret_cast列表中,但可能会导致未定义的行为,原因与< code>std::bit_cast拒绝的原因相同。在典型的实现中,您的< code>z大于< code>y,因此占用了< code>y的存储位置之外的位。在这种情况下,最好使用< code>std::bit_cast,它不会编译未定义的行为,但会拒绝编译。

double z = static_cast<double> (y);//but this is ok!!!

但这是完全正确的。它实际上与

double z = y;

编译器甚至不会对后者发出警告。然而,当< code>y的取值范围不完全符合< code>z时,则不清楚这是否是有意的。在这种情况下,最好用前者来表明意图。

const int y = 3;
int z = const_cast<int> (y);//error

很好。荒谬const_cast编译!或者您尝试实现的效果与可读性更强的效果有何不同

int z = y;

我会写那个。请描述一下你会写前一个的情况。

int z = const_cast<int&> (y);//ok

工程,但同样是不必要的,像以前一样令人困惑。我只会在这种情况下使用< code>const_cast:

int x;
const int& y = x;
int& z = const_cast<int&> (y);
z = 42;

在这里,我知道通过引用const y来引用的东西最初确实不是常量,因此将其修改为42并不是未定义的行为。

关于< code>dynamic_cast,您的示例完全不理解它想要做的事情:

Gun newGun1 = dynamic_cast<Gun>(tt);//error

它可能会尝试做这样的事情:

Gun newGun1 = tt;

这是编译的。然而,结果是newGun1初始化了机枪tt基子对象,这通常是编程错误。然而,你试图用石膏实现的目标仍然是完全黑暗的。

阎声
2023-03-14

只有static_cast才能返回所需类型的对象

这是不正确的。当强制转换目标是对象类型时,所有强制转换都返回一个对象。

上面写着:

  • constcast目标只能是引用、对象指针或成员指针。这是因为其他类型不是其“内部”类型的cv限定符可以修改的复合类型
  • dynamic_cast目标只能是对象的引用或指针。没有间接就不能有多态性。引用和指针是C中存在的间接形式
 类似资料:
  • 问题内容: 以下是ajax请求。 这就是delete.php 运行代码后,它将成功删除文件,但不会显示任何消息。 我也尝试将ajax请求更改为: 仍然不显示该消息。所以我想在delete.php文件中出了点问题。请帮忙。 问题答案: 进行jquery + ajax + php的最佳方法如下: jQuery的: PHP:

  • Clang和GCC都抱怨格式不正确,并给出了奇怪的诊断。 Clang报告 GCC报告 但是,根据expr.static.cast#4 如果存在从E到T的隐式转换序列([over.best.ics]),则表达式E可以显式转换为类型T 将一个类型转换为同一类型不是叫做标识转换吗? over.best.ics#General-8 如果不需要转换来将参数与参数类型匹配,则隐式转换序列是由标识转换([ove

  • 我读过这篇文章:java中arrays.aslist(array)与新arraylist (arrays.aslist(ia))之间的差异 当然,包装器上不允许一些列表操作,比如从列表中添加或删除元素,您只能读取或覆盖元素。 如果list2有List接口的引用,我期望它用Java实现List接口中包含的所有方法。https://docs.oracle.com/javase/7/docs/api/j

  • 所以我问了这个问题,我正在通过解决它。(顺便说一句,它确实解决了问题,我只是不确定我是否理解原因。) 在代码中: 只是构造一个R值吗?这和仅仅打电话有什么区别: 编辑: 根据答案推断,< code>static_cast似乎确实构造了一个R值< code > int :http://ideone.com/dVPIhD 但此代码在Visual Studio 2015上不起作用。这是编译器错误吗?此处

  • 为什么findElement(By)的返回类型是WebElement? 我知道文档中提到了返回类型是Webelment,但有人能解释一下为什么返回类型是Webelment吗。 我对这个话题的研究。 因为我们使用findElement搜索元素,webelement类用于表示HTML元素。 请让我知道我的想法是否正确或有任何具体原因

  • } 为什么和什么时候我们使用返回类型的new关键字,有谁能解释一下代码的最后一行吗??