gpt4 book ai didi

c++ - 在我错的地方用 C++ 切片?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:14 28 4
gpt4 key购买 nike

我阅读了 C++ 中的切片问题,并尝试了一些示例(我来自 Java 背景)。不幸的是,我不理解某些行为。目前,我被困在这个例子中(Efficent C++ 第三版的替代例子)。谁能帮我理解一下?

我的简单父类:

class Parent
{
public:

Parent(int type) { _type = type; }

virtual std::string getName() { return "Parent"; }

int getType() { return _type; }

private:

int _type;
};

我的简单 Child 类:

class Child : public Parent
{

public:

Child(void) : Parent(2) {};

virtual std::string getName() { return "Child"; }
std::string extraString() { return "Child extra string"; }
};

主要内容:

void printNames(Parent p)
{
std::cout << "Name: " << p.getName() << std::endl;

if (p.getType() == 2)
{
Child & c = static_cast<Child&>(p);
std::cout << "Extra: " << c.extraString() << std::endl;
std::cout << "Name after cast: " << c.getName() << std::endl;
}
}

int main()
{
Parent p(1);
Child c;

printNames(p);
printNames(c);
}

执行后我得到:

姓名:家长

姓名:家长

额外:子额外字符串

Actor 后的名字: parent

我理解前两行,因为它是“切片”的原因。但我不明白为什么我可以通过静态转换将 child 转换为 parent 。书中写到,切片后,所有的专业信息都会被切片掉。所以我想,我不能将 p 转换为 c,因为我没有信息(在函数 printNames 的开头创建了一个没有附加信息的新父对象) .

此外,如果转换成功,为什么我得到的是“转换后的名字: parent ”而不是“转换后的名字: child ”?

最佳答案

你的结果是非常不幸的一击。这是我得到的结果:

Name: Parent
Name: Parent
Extra: Child extra string
bash: line 8: 6391 Segmentation fault (core dumped) ./a.out

这是您的代码中发生的事情:

当您将 c 传递给 printNames 时,会发生转换。特别是,由于传递是按值传递的,因此您调用了 Parent 的复制构造函数,它是隐式声明的,其代码如下所示:

Parent(Parent const& other) : _type{other._type} {}

换句话说,您复制了c_type 变量,没有别的。你现在有一个 new 类型为 Parent 的对象(它的静态和动态类型都是 Parent)并且 c 是根本没有真正传递给 printNames

在函数内部,您随后强制将 p 转换为 Child&。这个转换不能成功,因为 p 根本不是一个 Child,也不能转换成一个,但是 C++ 没有给你任何诊断(这实际上是一种耻辱,因为编译器可以简单地证明转换是错误的)。

现在我们处于未定义行为的领域,现在一切都允许发生。实际上,由于 Child::extraString 从不访问 this(无论是隐式还是显式),对该函数的调用只会成功。该调用是在一个非法对象上完成的,但由于该对象从未被触及,因此有效(但仍然是非法的!)。

下一个对 Child::getName 的调用是一个虚拟调用,因此它需要显式访问 this(在大多数实现中,它访问虚拟方法表指针)。再一次,因为代码无论如何都是 UB,所以任何事情都可能发生。你很“幸运”,代码只是捕获了父类的虚方法表指针。使用我的编译器,访问显然失败了。

关于c++ - 在我错的地方用 C++ 切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25054489/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com