我想拥有整洁的头文件,其中首先列出了公共成员,然后是私有成员。
class A
{
public:
A() : y(0), z(0), x(y + z)
{}
int x;
private:
int y;
int z;
};
成员是按照声明的顺序初始化的,所以此构造函数有很多问题,因为x使用x时不会初始化y和z。
这只是我可以编写x(0)的示例,但是如果这些不是整数而是更大的类型,那将很麻烦。 为了解决这个问题,我需要先列出私有成员y和z, 然后是公共成员x。 在初始化程序列表中首先对其进行初始化的同时,有什么方法可以让我的私有成员留在底部?
如果没有,请指导我如何订购会员,因为我在网上找不到任何示例。首先列出一些公开的成员,然后列出一些私有的成员,然后更多的公开成员对我来说似乎很肮脏,但也许我错了。
答案 0 :(得分:4)
使用委派的构造函数,您可以将其编写为:
class A
{
public:
A() : A(0, 0) { }
{}
int x;
private:
explicit A(int y_, int z_) : x(y_ + z_), y(y_), z(z_) { }
int y;
int z;
};
答案 1 :(得分:3)
作为一种语言,C ++不能很好地将实现细节保留在头文件之外,或者通常与接口分开。您在这里所做的任何事情都会让步。
一种严格的方法是不包含任何公共成员变量,并为此分离并公开纯虚拟接口(在单独的文件中)。到那时,实际的类甚至都不需要在标头中-只需在源文件中,由工厂函数引用即可-因此剩余的标头就如您所愿。这不是我推荐的方法。
无论如何,C ++中有各种实际考虑因素会限制类成员的顺序。将所有公众成员放在班上最高级是一个不错的计划A,但有时它不会奏效,我也不建议您花大力气将其付诸实践。
答案 2 :(得分:2)
有什么方法可以让我的私人成员在最先初始化的同时留在底部
不。成员按声明顺序初始化;没有办法解决。
如果您只希望将成员除班级顶部之外的其他地方,则可以使用基数:
struct B {
int y;
int z;
};
class A : B
{
public:
A() : B{0, 0}, x(y + z)
{}
int x;
};
首先列出一些公开的成员,然后列出一些私有的成员,然后更多的公开成员对我来说似乎很肮脏,但也许我错了。
在您的情况下这不是必需的,因为您可以先放置所有私有内容,然后再放置所有公共内容。但是总的来说,使用相同的访问说明符分割声明就可以了。尽管很少需要。
答案 3 :(得分:0)
问题在于X取决于Y和Z,但是Y和Z是已知的。 您可能会寻求解决的方法:
(1)传入构造的X,而不是让构造函数创建它。
int y = 1;
int z = 40;
int x = y + z;
A(y, z, x);
(2)一个更疯狂的想法(请不要这样做,它通常表示您如何分解代码的问题)。创建一个默认对象,然后使用new放置。但是,当我看到这样的代码时,通常是使用init()
函数或其他函数。对于int来说,这是一个超级杀伤力,但我假设您使用的是更复杂的类型,这就是您这样做的原因。
A() : y(0), z(0), x(/*default construct*/)
{
new (&x) int(y + z);
}
//or
A() : y(0), z(0), x(/*default construct*/)
{
x.init(y, z);
}
总的来说,我认为您应该重新评估X为何依赖Y和Z,并可能重新整理一些数据和职责。
如果X依赖于Y和Z的状态,则可能希望将其用作函数(如果在类外部使用它),因为作为公共成员变量,其他人可以对其进行修改并可能使其与X脱离同步和Y。您可能还想将Y和Z放在X的内部。