我是编程c ++的新用户。当我不用new创建派生实例时,它调用Base :: test()。 那么Base b = d和Base * b1 = new Derived()?
之间有什么区别?基础课程
#include <iostream>
class Base
{
public:
virtual void test() { std::cout << "Base::test()" << std::endl; };
};
派生类
#include "Base.h"
class Derived : public Base
{
public:
void test() { std::cout << "Derived::test()" << std::endl; };
}
main.cc
#include "Derived.h"
int main()
{
Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
Base* b1 = new Derived();
b1->test();
delete b1;
return 0;
}
答案 0 :(得分:2)
Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
您创建了Derived
对象d
和Base
对象b
。后来分配b=d;
这里发生了对象切片。作业b
仅包含Base
类信息的Derived
部分。因此,当您致电b.test()
时,它会调用Base::test()
代替Derived::test()
函数。
Base* b1 = new Derived();
b1->test();
delete b1;
在这里,您在堆中动态创建了一个Derived类对象,并将该对象的指针返回给Base类指针。这里的指针只是保存Derived
类对象的内存地址。当您调用b->test()
时,系统会在内部动态识别对象的类型,并将其作为Derived
返回。因此它会调用Derived::test()
函数。
答案 1 :(得分:0)
因为这不是在C ++中实现多态的方式。
此:
Base b;
b = d;
第二个语句调用b的赋值运算符,即b仍然是类Base的对象b(除了数据现在可能不同,但是方法集合,即类型仍然是Base)。
您需要操作指针而不是引用,因为引用无法更改且不会更改。
答案 2 :(得分:0)
你在c ++中有两个重要概念之间的网格。
在c ++运行时,多边形是在虚函数的帮助下使用基类指针实现的。由于实际类型的对象是在运行时决定的。我们知道基类指针可以存储派生类的对象。然后调用任何函数调用派生类函数(如果base是虚函数)。
在您的情况下,您将派生类的对象分配给基类的对象。这是Object slicing。