如何在派生类构造函数中初始化基类成员变量?

时间:2011-09-13 17:09:52

标签: c++ inheritance

为什么我不能这样做?

class A
{
public:
    int a, b;
};

class B : public A
{
    B() : A(), a(0), b(0)
    {
    }

};

8 个答案:

答案 0 :(得分:109)

您无法在a中初始化bB,因为他们不是B的成员。他们是A的成员,因此只有A可以初始化它们。您可以将它们公开,然后在B中进行分配,但这不是推荐选项,因为它会破坏封装。相反,在A中创建一个构造函数,以允许B(或A的任何子类)初始化它们:

class A 
{
protected:
    A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
    // Change "protected" to "public" to allow others to instantiate A.
private:
    int a, b; // Keep these variables private in A
};

class B : public A 
{
public:
    B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
    {
    } 
};

答案 1 :(得分:22)

不考虑它们是private这一事实,因为abA的成员,它们应由A初始化s构造函数,而不是其他类的构造函数(派生或不派生)。

尝试:

class A
{
    int a, b;

protected: // or public:
    A(int a, int b): a(a), b(b) {}
}

class B : public A
{
    B() : A(0, 0) {}
}

答案 2 :(得分:2)

# include<stdio.h>
# include<iostream>
# include<conio.h>

using namespace std;

class Base{
    public:
        Base(int i, float f, double d): i(i), f(f), d(d)
        {
        }
    virtual void Show()=0;
    protected:
        int i;
        float f;
        double d;
};


class Derived: public Base{
    public:
        Derived(int i, float f, double d): Base( i, f, d)
        {
        }
        void Show()
        {
            cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
        }
};

int main(){
    Base * b = new Derived(10, 1.2, 3.89);
    b->Show();
    return 0;
}

这是一个工作示例,以防您想要初始化Derived类对象中存在的Base类数据成员,而您希望通过Derived类构造函数调用来推送这些值。

答案 3 :(得分:2)

以某种方式,没有人列出最简单的方法:

class A
{
public:
    int a, b;
};

class B : public A
{
    B()
    {
        a = 0;
        b = 0;
    }

};

您无法访问初始值设定项列表中的基成员,但构造器本身可以访问其他基类的publicprotected成员。

答案 4 :(得分:1)

虽然这在极少数情况下很有用(如果不是这种情况,语言会直接允许它),请查看Base from Member idiom。它不是一个免代码解决方案,你必须添加一个额外的继承层,但它可以完成工作。为避免样板代码,您可以使用boost's implementation

答案 5 :(得分:0)

你为什么不能这样做?因为该语言不允许您在派生类的初始化列表中初始化基类'成员。

你怎么能这样做?像这样:

class A
{
public:
    A(int a, int b) : a_(a), b_(b) {};
    int a_, b_;
};

class B : public A
{
public:
    B() : A(0,0) 
    {
    }
};

答案 6 :(得分:-1)

如果未指定类成员的可见性,则默认为“private”。如果要在子类中访问它们,则应将您的成员设为私有或受保护。

答案 7 :(得分:-1)

聚合类(如示例中的A(*))必须将其成员设为公共,并且没有用户定义的构造函数。它们与初始化列表初始化,例如, A a {0,0};或您的B() : A({0,0}){}。基本聚合类的成员不能在派生类的构造函数中单独初始化。

(*)准确地说,正如前面提到的那样,由于私有非静态成员,原始class A不是聚合