C++ 将派生类构造函数分配给基类指针
我试图理解虚拟函数,遇到了以下代码C++ 将派生类构造函数分配给基类指针,c++,pointers,inheritance,constructor,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 Ba
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"
类基
{
公众:
void Method1(){std::cout将使用调用构造函数的结果初始化它。
调用new-Derived()创建指向新派生对象的指针。
由于类派生是从类基公开派生的,所以指向的新对象是一个基(同时也是派生对象)。它是用调用构造函数的结果初始化的。
调用new-Derived()创建指向新派生对象的指针。
由于派生类公开从基类派生,因此指向的新对象是基类(同时也是派生对象)。C++允许从派生指针类型隐式转换为基类指针类型。这是安全的,因为派生类型的内存布局与基类大小相同
但是,您的示例有一个潜在的错误,因为您已经失去了对obj
的真实类型的跟踪。当需要删除它时,您将调用错误的析构函数。这可以通过使析构函数虚拟来弥补。C++允许从派生指针类型隐式转换为基指针类型。这是安全的,因为内存派生类型的yout与基类的大小相同
但是,您的示例有一个潜在的错误,因为您已经失去了对obj
的实际类型的跟踪。当需要删除它时,您将调用错误的析构函数。这可以通过使析构函数虚拟来弥补。对于表达式
obj->Method1 (); // Prints "Base::Method1"
obj->Method2 ();
…编译器看到一个指向Base
实例对象的指针。它查找一个名为Method1
的方法。它发现它是一个非虚拟方法。因此它静态绑定它(即在编译时),并生成“直接”调用Base::Method1
的代码
对于表达式
obj->Method1 (); // Prints "Base::Method1"
obj->Method2 ();
…编译器看到一个指向Base
实例对象的指针。它查找一个名为Method2
的方法。它发现它是一个虚拟方法。因此它不会静态绑定它(也称为编译时绑定),但生成运行时查找实例对象的实际类的代码。obj
指向。在运行时,存在一个Derived
的实例对象。因此,将找到并执行Derived::Method2
让我们引用伟大的艾伦·凯的话来总结一下:
实际上,我提出了“面向对象”一词,我可以告诉你我没有C++。
obj->Method1 (); // Prints "Base::Method1"
obj->Method2 ();
…编译器看到一个指向Base
实例对象的指针。它查找一个名为Method1
的方法。它发现它是一个非虚拟方法。因此它静态绑定它(即在编译时),并生成“直接”调用Base::Method1
的代码
对于表达式
obj->Method1 (); // Prints "Base::Method1"
obj->Method2 ();
…编译器看到一个指向Base
实例对象的指针。它查找一个名为Method2
的方法。它发现它是一个虚拟方法。因此它不会静态绑定它(也称为编译时绑定),但生成运行时查找实例对象的实际类的代码。obj
指向。在运行时,存在一个Derived
的实例对象。因此,将找到并执行Derived::Method2
让我们引用伟大的艾伦·凯的话来总结一下:
实际上,我提出了“面向对象”一词,我可以告诉你我没有C++。