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

时间:2016-12-14 14:49:55

标签: c++ constructor late-binding early-binding

考虑以下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

我使用类varA的构造函数初始化C对象。调用A和C类的构造函数,但varA只是一个A对象。我将varA的地址转换为C*类型,我尝试调用其f()函数,但它会打印f()A函数,所以我推断它是使用早期绑定机制来调用它。 我想如果我调用派生类的构造函数,就像这种情况一样,如果我调用了基本构造函数,我会获得相同的对象。 我认为唯一的区别是其他构造函数被称为。我的假设是正确的还是有其他差异?

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

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

done = False

def check():
    global done
    while True:
        if sys.stdin.read() == 'terminate':
            done = True
            break
def sniff(someparams):
    global done
    done = False
    input_thread = threading.Thread(target=check)
    input_thread.daemon = True
    input_thread.start()
    while True:
        #do some stuff
        if done:
            break