3

在 Bruce Eckel “Thinking in C++”的帮助下学习 C++。坚持练习 30。这里是:

如果对按值传递的对象的函数调用不是早期绑定的,则虚拟调用可能会访问不存在的部分。这可能吗?编写一些代码来强制进行虚拟调用,看看这是否会导致崩溃。要解释这种行为,请检查按值传递对象时会发生什么。

我可以理解为对象调用虚函数的结果,但是如果没有调用适当的构造函数,我无法理解如何强制编译器执行此操作。

有没有办法在不调用适当的构造函数或运算符(用于类型转换)的情况下将一个对象视为另一个对象?

4

2 回答 2

2

Bruce 试图说明对象切片,即多态对象按值传递的情况。

您可以这样做:

#include <iostream>
using namespace std;
struct hello {
    virtual void say() { cout << "hello" << endl; }
};
struct world : public hello {
    virtual void say() { cout << "world" << endl; }
};
void force(hello h) {
    h.say();
}
int main() {
    world w;
    w.say();
    force(w);
    return 0;
}

此代码输出(链接到 ideone

world
hello

即使您希望类型的对象是world"say" world,而不是hello. C++ 编译器很聪明地注意到它w是按值传递hello的,因此它会调整 vtable 以避免调用派生类中的方法。


测试您是否了解通过引用传递的奖励练习:您可以修改我的代码以使其打印world world吗?您可以插入单个字符。

于 2012-10-18T15:06:22.583 回答
0

尽管没有适当的运算符就无法将对象从一种类型转换为另一种类型,但您可以使用指针并使用 static_cast<> 或 dynamic_cast<> 或 reinterpret_cast<> 进行强制转换

于 2012-10-18T14:59:35.493 回答