我如何初始化派生类构造函数中的基类成员variables?
为什么我不能这样做?
class A { public: int a, b; } class B : public A { B() : A(), a(0), b(0) { } }
你不能在B
初始化a
和b
,因为它们不是B
成员。 他们是A
成员,因此只有A
可以初始化他们。 你可以把它们公开,然后在B
进行赋值,但这不是推荐的选项,因为它会破坏封装。 相反,在A
创build一个构造函数来允许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. { } };
撇开它们是private
的事实,因为a
和b
是A
成员,它们是由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) {} }
虽然在极less数情况下这是有用的(如果情况并非如此,那么语言会直接允许),请参阅成员用语中的Base 。 这不是一个无代码的解决scheme,你必须添加一个额外的inheritance层,但它完成了工作。 为了避免样板代码,你可以使用boost的实现
如果您不指定类成员的可见性,则默认为“私有”。 你应该让你的成员是私人的或保护,如果你想访问他们在一个子类。
你为什么不能做到这一点? 因为这个语言不允许你在派生类的初始化列表中初始化一个基类的成员。
你怎么能做到这一点? 喜欢这个:
class A { public: A(int a, int b) : a_(a), b_(b) {}; int a_, b_; }; class B : public A { public: B() : A(0,0) { } };
在你的例子(*)中类似A的聚合类必须公开其成员,并且没有用户定义的构造函数。 它们初始化列表初始化,例如A a {0,0};
或在你的情况B() : A({0,0}){}
。 基类聚合类的成员不能在派生类的构造函数中单独初始化。
(*) 准确地说,正确地提到,由于私有非静态成员,原始class A
不是聚合
# 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类构造函数调用来推送这些值,则这是一个有效的示例。