将派生类构造函数分配给基类指针

时间:2016-08-02 17:37:39

标签: c++ pointers inheritance constructor

我试图理解虚函数,并遇到了以下代码。

class Base
{
  public:
            void Method1 ()  {  std::cout << "Base::Method1" << std::endl;  }
    virtual void Method2 ()  {  std::cout << "Base::Method2" << std::endl;  }
};

class Derived : public Base
{
  public:
    void Method1 ()  {  std::cout << "Derived::Method1" << std::endl;  }
    void Method2 ()  {  std::cout << "Derived::Method2" << std::endl;  }
};

Base* obj = new Derived ();
  //  Note - constructed as Derived, but pointer stored as Base*

obj->Method1 ();  //  Prints "Base::Method1"
obj->Method2 ();  //  Prints "Derived::Method2"

接下来,如何使用派生类Constructor初始化Base类指针?

3 个答案:

答案 0 :(得分:3)

C ++允许从派生指针类型到基指针类型的隐式转换。这是安全的,因为派生类型的内存布局与基类的内存大小相同。

你的例子有一个潜在的错误,因为你已经忘记了obj的真实类型。当需要删除它时,您将调用错误的析构函数。这可以通过使析构函数虚拟来解决。

答案 1 :(得分:0)

使用对构造函数的调用结果初始化它。 调用new Derived()会创建一个指向新Derived对象的指针。 并且由于类Derived从类Base公开派生,所指向的新对象是一个基础(同时作为派生)。

答案 2 :(得分:0)

表达式......

obj->Method1 ();  //  Prints "Base::Method1"

... 编译器看到指向Base的实例对象的指针。它查找名为Method1的方法。它将其视为非虚拟方法。所以它静态地绑定它(也就是在编译时),并生成直接&#34;直接&#34;致电Base::Method1

表达式......

obj->Method2 ();  

...编译器看到指向Base的实例对象的指针。它查找名为Method2的方法。它将其视为虚拟方法。因此它不会静态绑定它(也就是在编译时),但会在实例对象obj指向的实际类上生成运行时查找代码。在运行时,有一个Derived的实例对象。因此,Derived::Method2将被找到并执行。

让我们用伟大的Alan Kay的一句话来概括:

实际上我编写了术语&#34;面向对象&#34;,我可以告诉你我没有考虑到C ++。