重写的函数不会反映在基 class 中,这是正常行为吗?
Overridden function does not reflect in the base class, is this a normal behavior?
给定以下代码:
class Base {
public:
virtual void Test() {
cout << "Not Overridden" << endl;
}
};
class Derived : public Base {
public:
void Test() override {
cout << "Overridden" << endl;
}
};
int main() {
Base o = Derived();
o.Test();
return 0;
}
像我这样来自 Java 背景的人希望编译器输出 Overridden
但令人惊讶的是输出恰恰相反。
如果这是正常行为,那么 C++ 中的继承有什么意义?
我缺少什么?
是的,这是正常行为,多态性仅适用于指针和引用。
使用原始指针:
int main() {
Base* o = new Derived();
o->Test();
delete o; //when done with using it delete it from memory
//...
}
此内存管理的替代方法是使用 smart pointers.
使用智能指针:
int main() {
unique_ptr<Base> o(new Derived); // automatic memory management
o->Test();
//...
}
参考:
int main() {
Derived d;
Base& o = d;
o.Test();
//...
}
这是你需要注意的事情,当声明 Derived
对象的块超出范围时,引用将变得无用,例如,如果你 return 它来自函数。
输出:
Overridden
网站上的一些帖子解释了为什么会这样,例如 this one。
你的方式导致 object slicing。
您还需要添加一个 virtual destructor 到您的基础 class。
Base o = Derived();
o
以上是一个 对象 – 一个 Base
对象 – 而不是 Derived
一。 o
对象是通过 object slicing 从 Derived
对象创建的,但 o
仍然是 Base
对象。这里没有动态调度,所以 o.Test()
导致 Base::Test()
被调用。
相反,如果您将 o
声明为指向您创建的 Derived
对象的 Base
指针:
Base* o = new Derived();
o->Test();
在这种情况下,o
是指向对象的 指针 – 而不是对象 – 并且动态调度生效:即使 o
是指向 Base
对象的指针,它绑定到 Derived
对象,因此 o->Test()
由于动态调度导致 Derived::Test()
这次被调用。
类似地,如果 o
是对 Base
的引用而不是指针。
给定以下代码:
class Base {
public:
virtual void Test() {
cout << "Not Overridden" << endl;
}
};
class Derived : public Base {
public:
void Test() override {
cout << "Overridden" << endl;
}
};
int main() {
Base o = Derived();
o.Test();
return 0;
}
像我这样来自 Java 背景的人希望编译器输出 Overridden
但令人惊讶的是输出恰恰相反。
如果这是正常行为,那么 C++ 中的继承有什么意义?
我缺少什么?
是的,这是正常行为,多态性仅适用于指针和引用。
使用原始指针:
int main() {
Base* o = new Derived();
o->Test();
delete o; //when done with using it delete it from memory
//...
}
此内存管理的替代方法是使用 smart pointers.
使用智能指针:
int main() {
unique_ptr<Base> o(new Derived); // automatic memory management
o->Test();
//...
}
参考:
int main() {
Derived d;
Base& o = d;
o.Test();
//...
}
这是你需要注意的事情,当声明 Derived
对象的块超出范围时,引用将变得无用,例如,如果你 return 它来自函数。
输出:
Overridden
网站上的一些帖子解释了为什么会这样,例如 this one。
你的方式导致 object slicing。
您还需要添加一个 virtual destructor 到您的基础 class。
Base o = Derived();
o
以上是一个 对象 – 一个 Base
对象 – 而不是 Derived
一。 o
对象是通过 object slicing 从 Derived
对象创建的,但 o
仍然是 Base
对象。这里没有动态调度,所以 o.Test()
导致 Base::Test()
被调用。
相反,如果您将 o
声明为指向您创建的 Derived
对象的 Base
指针:
Base* o = new Derived();
o->Test();
在这种情况下,o
是指向对象的 指针 – 而不是对象 – 并且动态调度生效:即使 o
是指向 Base
对象的指针,它绑定到 Derived
对象,因此 o->Test()
由于动态调度导致 Derived::Test()
这次被调用。
类似地,如果 o
是对 Base
的引用而不是指针。