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

为什么我不能这么做?

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


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


};
191573 次浏览

撇开它们是 private这个事实不谈,因为 abA的成员,它们应该由 A的构造函数初始化,而不是由其他类的构造函数(派生的或非派生的)初始化。

试试:

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) {}
};

不能在 B中初始化 ab,因为它们不是 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.
{
}
};

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

(*) 准确地说,正如我们正确地提到的,由于私有的非静态成员,原来的 class A不是一个聚合

你为什么做不到?因为该语言不允许在派生类的初始值设定项列表中初始化基类的成员。

你怎么做到的? 像这样:

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


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

虽然这在少数情况下很有用(如果不是这样,语言会直接允许) ,但是看看 成员成语的基础。这不是一个无代码的解决方案,您必须添加一个额外的继承层,但它可以完成工作。为了避免样板代码,您可以使用 推广计划的实施

# 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;
}

这是一个工作示例,用于初始化派生类对象中存在的 Base 类数据成员,而通过派生类构造函数调用推送这些值的接口。

不知为何,没有人列出最简单的方法:

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


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


};

您不能访问初始值设定项清单中的基底成员,但是构造函数本身,就像任何其他成员方法一样,可以访问基底类别的 publicprotected成员。