[英]How can I initialize a member const reference in a derived class, when I wish to call a base class constructor?
[英]How can I initialize base class member variables in derived class constructor?
为什么我不能这样做?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
您不能在B
初始化a
和b
,因为它们不是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.
{
}
};
撇开它们是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) {}
};
不知何故,没有人列出最简单的方法:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
您不能访问初始化列表中的基成员,但是构造函数本身,就像任何其他成员方法一样,可以访问基类的public
成员和protected
成员。
# 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;
}
这是一个工作示例,如果您想初始化派生类对象中存在的基类数据成员,而您想通过派生类构造函数调用推送这些值接口。
虽然这在极少数情况下很有用(如果不是这种情况,语言将直接允许它),请查看Member idiom中的Base 。 这不是无代码解决方案,您必须添加额外的继承层,但它可以完成工作。 为了避免样板代码,您可以使用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,必须将其成员设为 public,并且没有用户定义的构造函数。 它们被初始化列表初始化,例如A a {0,0};
或者在你的情况下B() : A({0,0}){}
。 基聚合类的成员不能在派生类的构造函数中单独初始化。
(*)准确地说,正如正确提到的,由于私有非静态成员,原始class A
不是聚合
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.