初始化派生类的成员(C ++)

时间:2011-05-11 15:33:13

标签: c++ constructor derived-class initializing

初始化从其基类中转换的派生类的首选方法是什么?

考虑以下情况:

    class A{
        public:
           A();
           ~A();
    }

    class B : public A{
        public:
           B() {m_b = 0.0;};
           ~B();
           float GetValue(){return m_b;};

        private: 
           float m_b;
    }


    A* a = new A;
    B* b = static_cast<B*>(a);

    float val = b->GetValue();   // This was never initialized because it was not constructed

我目前的解决方案是手动调用Initialize()函数,该函数将按照构造函数执行必要的初始化。

虽然看起来很草率,但必须有更好/更清洁的方法。

非常感谢任何帮助和指导!

6 个答案:

答案 0 :(得分:5)

这是一个错误的结构:

A* a = new A;
B* b = static_cast<B*>(a);

修改

应该是:

B* b = new B();

因为,正如sbi指出的那样,A没有一个名为GetValue()的虚函数,因此永远无法从A调用它。

不要从A *到B *进行static_cast。

答案 1 :(得分:2)

您正在将父对象强制转换为派生类型的对象。这是完全错误的。 A类的对象没有要初始化的m_b成员。

答案 2 :(得分:0)

我不确定它是否有效,因为该对象是使用sizeof(A)创建的,而sizeof(B)显然更大。

答案 3 :(得分:0)

您描述的代码是危险且无效的,因为B是A,但不是相反。这是有效的:

B* b = new B;
A* a = dynamic_cast<A*>(b);

答案 4 :(得分:0)

您没有要初始化的派生类的实例 - 您只有基类的实例。所有1static_cast1都在强制编译器允许您将基类视为派生类。

相反,要创建B,您应该这样做:

A* a = new B;

这会调用B的构造函数,将m_b初始化为0.0

答案 5 :(得分:0)

B* b = static_cast<B*>(a);

只有当您知道static_cast实际指向a的对象或来自B的类时,您才应该使用此B,这显然不是案件。

这是一个不正确的陈述 有效序列应为:

 A* a = new B();
 B* b = static_cast<B*>(a);

a现在指向B类型的对象。它可以这样做,因为 指向Base类对象的指针始终指向派生类的对象,只要它是公共派生。

现在,您可以使用static_cast,因为您确定a实际指向class B的对象。
可能存在这样的情况,其中一个不知道类的层次结构,并且在这种情况下不能使用static_cast C ++在这种情况下提供另一个名为Dynamic_cast的强制转换类型,如果如果是指针,则cast无效,或者在引用的情况下抛出异常。

请注意,尽管Dynamic_Cast仅适用于多态类。