C++ 如何在派生类构造函数中初始化基类成员变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7405740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I initialize base class member variables in derived class constructor?
提问by amrhassan
Why can't I do this?
为什么我不能这样做?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
回答by In silico
You can't initialize a
and b
in B
because they are not members of B
. They are members of A
, therefore only A
can initialize them. You can make them public, then do assignment in B
, but that is not a recommended option since it would destroy encapsulation. Instead, create a constructor in A
to allow B
(or any subclass of A
) to initialize them:
你不能初始化a
and b
inB
因为它们不是B
. 它们是 的成员A
,因此只能A
初始化它们。您可以将它们设为公开,然后在 中进行赋值B
,但这不是推荐的选项,因为它会破坏封装。相反,创建一个构造函数 inA
以允许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.
{
}
};
回答by NPE
Leaving aside the fact that they are private
, since a
and b
are members of A
, they are meant to be initialized by A
's constructors, not by some other class's constructors (derived or not).
撇开它们是 的事实private
,因为a
并且b
是 的成员A
,它们应该由A
的构造函数初始化,而不是由其他类的构造函数(派生与否)初始化。
Try:
尝试:
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) {}
};
回答by Violet Giraffe
Somehow, no one listed the simplest way:
不知何故,没有人列出最简单的方法:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
You can't access base members in the initializer list, but the constructor itself, just as any other member method, may access public
and protected
members of the base class.
您不能访问初始化列表中的基成员,但是构造函数本身,就像任何其他成员方法一样,可以访问基类的public
和protected
成员。
回答by manish srivastava
# 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;
}
It's a working example in case you want to initialize the Base class data members present in the Derived class object, whereas you want to push these values interfacing via Derived class constructor call.
这是一个工作示例,如果您想初始化派生类对象中存在的基类数据成员,而您想通过派生类构造函数调用推送这些值接口。
回答by Nikos Athanasiou
While this is usefull in rare cases (if that was not the case, the language would've allowed it directly), take a look at the Base from Member idiom. It's not a code free solution, you'd have to add an extra layer of inheritance, but it gets the job done. To avoid boilerplate code you could use boost's implementation
虽然这在极少数情况下很有用(如果不是这种情况,语言将直接允许它),请查看Member idiom中的Base。这不是无代码解决方案,您必须添加额外的继承层,但它可以完成工作。为了避免样板代码,您可以使用boost 的实现
回答by John Dibling
Why can't you do it? Because the language doesn't allow you to initializa a base class' members in the derived class' initializer list.
为什么你做不到?因为该语言不允许您在派生类的初始化列表中初始化基类的成员。
How can you get this done? Like this:
你怎么能做到这一点?像这样:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
回答by Macondo2Seattle
If you don't specify visibility for a class member, it defaults to "private". You should make your members private or protected if you want to access them in a subclass.
如果您没有为类成员指定可见性,则默认为“私有”。如果您想在子类中访问它们,您应该将您的成员设为私有或受保护。
回答by Gene Bushuyev
Aggregate classes, like A in your example(*), must have their members public, and have no user-defined constructors. They are intialized with initializer list, e.g. A a {0,0};
or in your case B() : A({0,0}){}
. The members of base aggregate class cannot be individually initialized in the constructor of the derived class.
聚合类,如您的示例(*)中的 A,必须将其成员设为 public,并且没有用户定义的构造函数。它们使用初始化列表进行初始化,例如A a {0,0};
或在您的情况下B() : A({0,0}){}
。基聚合类的成员不能在派生类的构造函数中单独初始化。
(*) To be precise, as it was correctly mentioned, original class A
is not an aggregate due to private non-static members
(*)准确地说,正如正确提到的,class A
由于私有非静态成员,原始不是聚合