gpt4 book ai didi

c++ - 添加字符串类型的类成员会导致调用基类函数而不是子类函数

转载 作者:行者123 更新时间:2023-12-02 22:28:15 25 4
gpt4 key购买 nike

为什么下面的代码打印 0,但是如果注释掉“std::string my_string”,它会打印 1?

#include <stdio.h>
#include <iostream>

class A {
public:
virtual int foo() {
return 0;
}
private:
std::string my_string;
};

class B : public A {
public:
int foo() {
return 1;
}
};

int main()
{
A* a;
if (true) {
B b;
a = &b;
}
std::cout << a->foo() << std::endl;
return 0;
}

我还了解到,将 std::string 更改为 std:string* 也会导致代码打印 1,就像删除 if 语句一样,尽管我不明白为什么其中任何一个都是正确的。

编辑:这似乎是由于悬空指针造成的。那么在 Java 中执行类似操作的 C++ 标准模式是什么:

Animal animal; 
boolean isDog = false;
// get user input to set isDog
if (isDog) {
animal = new Dog();
} else {
animal = new Cat();
}
animal.makeNoise(); // Should make a Dog/Cat noise depending on value of isDog.

最佳答案

问题

该程序有Undefined Behaviourb 仅在 if 主体内的范围内。访问 dangling pointer 时不能指望逻辑结果.

int main()
{
A* a;
if (true) {
B b; // b is scoped by the body of the if.
a = &b;
} // b's dead, Jim.
std::cout << a->foo() << std::endl; // a points to the dead b, an invalid object
return 0;
}

TL;灾难恢复解决方案

int main()
{
std::unique_ptr<A> a; // All hail the smart pointer overlords!
if (true) {
a = std::make_unique<B>();
}
std::cout << a->foo() << std::endl;
return 0;
} // a is destroyed here and takes the B with it.

说明

您可以将 a 指向具有动态生命周期的对象

int main()
{
A* a;
if (true) {
a = new B; // dynamic allocation
} // b's dead, Jim.
std::cout << a->foo() << std::endl;
delete a; // DaANGER! DANGER!
return 0;
}

不幸的是,delete a;也是未定义的行为,因为A有一个非虚拟析构函数。如果没有虚拟析构函数,a 指向的对象将被销毁为 A,而不是 B

解决这个问题的方法是为 A 提供一个虚拟析构函数,以允许它销毁正确的实例。

class A {
public:
virtual ~A() = default;
virtual int foo() {
return 0;
}
private:
std::string my_string;
};

无需修改 B,因为一旦函数被声明为 virtual,它就对其子函数保持 virtual 状态。 Keep an eye out for final .

但它是 best to avoid raw dynamic allocations ,因此我们还可以进行一项改进:Use Smart pointers .

这让我们回到了解决方案。

Documentation for std::unique_ptr

Documentation for std::make_unique

关于c++ - 添加字符串类型的类成员会导致调用基类函数而不是子类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58441459/

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