为什么我不能这样做?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
为什么我不能这样做?
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.
{
}
};
a
和 b
是私有的所以不能在 B::B()
中初始化它们,而是因为它们不是class B
的成员变量。如果你将它们声明为公有或保护的,你可以在 B::B()
的函数体内对它们进行赋值。 - R Samuel Klatchkoa
和 b
…”,后来改成了“你无法初始化…”,但没有确保句子的其余部分是合理的。帖子已编辑。 - In silico不考虑它们是 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
成员。
class A
内部,我们不能依赖于a
和b
已被初始化。例如,任何实现class C : public A
的代码都可能忘记调用a=0;
并留下未初始化的a
。 - Sparkofska# 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类的构造函数调用进行接口推送这些值,同时希望初始化Derived类对象中存在的Base类数据成员,那么这是一个工作示例。
为什么你不能这样做?因为该语言不允许你在派生类的初始化列表中初始化基类成员。
如何完成此操作?可以按照以下方式实现:
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
由于具有私有的非静态成员而不是聚合。