使用派生的 class 构造函数初始化对象

Initialize a object with a derived class constructor

考虑以下 C++ 代码:

#include <iostream>

using std::cout;

class A
{
public:
    int a;

    A():a(0)
    {
        cout << "A constructor\n";
    }

    virtual void f()
    {
        cout << "f inside A\n";
    }
};

class C : public A
{
public:
    int c;

    virtual void f()
    {
        cout << "f inside C\n";
    }

    C():c(0)
    {
        cout << "C constructor\n";
    }
};

int main()
{
    A varA = C();

    cout << "Size of C class: " << sizeof(C) << "\n";
    cout << "Size of varA object: " << sizeof(varA) << "\n";

    C* varC = static_cast<C*>(&varA);
    varC->f();

    cout << "varC->a is " << varC->a << "\n";
    cout << "varC->c is " << varC->c << "\n";
}

这个程序的输出是:

A constructor
C constructor
Size of C class: 16
Size of varA object: 8
f inside A
varC->a is 0
varC->c is 1726166356

我用classC的构造函数初始化了varA对象。 A 和 C class 的构造函数被调用,但是 varA 只是一个 A 对象。我将 varA 的地址转换为 C* 类型,并尝试调用它的 f() 函数,但它打印了 class [=16= 的 f() 函数],所以我推断它是使用早期绑定机制来调用它。 我想如果我像这种情况一样调用派生 class 的构造函数,我将获得与调用基本构造函数相同的对象。 我认为唯一的区别是调用了其他构造函数。我的推测对还是有什么不同?

切片的经典例子。 A varA = C(); 为您留下 A 的静态和动态类型的对象。结果,C* varC = static_cast<C*>(&varA); 表现出未定义的行为。

您可以将完整的派生 class 存储在基 class 指针中,但是:

int main() {        
  A* varA = new C();
  C* varC = static_cast<C*>(varA);
  varC->f();

  cout << "varC->a is " << varC->a << endl;
  cout << "varC->b is " << varC->b << endl;
  cout << "varC->c is " << varC->c << endl;
} // oops, forgot to delete varA/varC, memory leak!