Hyd*_*dra 3 c++ polymorphism inheritance
为什么下面的代码显示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;
}
Run Code Online (Sandbox Code Playgroud)
我也理解将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.
Run Code Online (Sandbox Code Playgroud)
该程序具有未定义的行为。b仅在身体的范围内if。访问悬空指针时,您不能指望逻辑结果。
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;
}
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
您可以指向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;
}
Run Code Online (Sandbox Code Playgroud)
不幸的delete a;是,由于A具有非virtual析构函数,因此也是未定义的行为。如果没有虚拟析构函数,则所指向的对象a将被破坏为A,而不是B。
解决方法是提供A一个虚拟析构函数,使其能够销毁正确的实例。
class A {
public:
virtual ~A() = default;
virtual int foo() {
return 0;
}
private:
std::string my_string;
};
Run Code Online (Sandbox Code Playgroud)
无需修改,B因为一旦声明了函数virtual,该函数将virtual为其子代保留。密切注意final。
但是最好避免原始的动态分配,因此我们可以做更多的改进:使用智能指针。
这使我们回到了解决方案。
| 归档时间: |
|
| 查看次数: |
40 次 |
| 最近记录: |