我有一个带有一些参数的构造函数.我假设它们是按照列出的顺序构建的,但在一种情况下,它们似乎是反向构造的,导致中止.当我颠倒论点时,程序停止了中止.这是我正在使用的语法的一个例子.问题是,在这种情况下,需要在b_之前初始化a_.你能保证施工顺序吗?
例如
class A
{
public:
A(OtherClass o, string x, int y) :
a_(o), b_(a_, x, y) { }
OtherClass a_;
AnotherClass b_;
};
Run Code Online (Sandbox Code Playgroud) 如果初始化列表顺序与类中的变量顺序不匹配,为什么gcc会抛出一个合适的东西呢?
class myClass
{
public:
int A;
int B;
myClass();
};
myClass::myClass() :
B(1),
A(2)
{}
Run Code Online (Sandbox Code Playgroud)
将导致:
file.h:274: warning: 'myClass::A' will be initialized after
file.h:273: warning: 'int myClass::B
file.cpp:581: warning: when initialized here
Run Code Online (Sandbox Code Playgroud)
发出这种警告有什么具体原因吗?是否存在与初始化类变量相关的风险,其顺序与在类中定义的顺序不同?
(注意,有一个问题触及了这个主题,但答案几乎是"因为它应该是这样"而没有给出任何理由,为什么应该订购,或者这有什么不对的故障 - 我会想知道为什么存在这样的限制 - 有人会举例说明它可能适得其反吗?)
在编写类的构造函数时,我经常会问自己是否应该使用初始化成员变量或构造函数参数.这里有两个例子来说明我的意思:
构造函数参数
class Foo {
public:
Foo(int speed) :
mSpeed(speed),
mEntity(speed)
{ }
private:
int mSpeed;
Entity mEntity;
}
Run Code Online (Sandbox Code Playgroud)
成员变量
class Foo {
public:
Foo(int speed) :
mSpeed(speed),
mEntity(mSpeed)
{ }
private:
int mSpeed;
Entity mEntity;
}
Run Code Online (Sandbox Code Playgroud)
更进一步,在构造函数体中使用变量会产生同样的问题.
构造函数参数
class Foo {
public:
Foo(int speed) :
mSpeed(speed)
{
mMonster.setSpeed(speed);
}
private:
int mSpeed;
Monster mMonster;
}
Run Code Online (Sandbox Code Playgroud)
成员变量
class Foo {
public:
Foo(int speed) :
mSpeed(speed)
{
mMonster.setSpeed(mSpeed);
}
private:
int mSpeed;
Monster mMonster;
}
Run Code Online (Sandbox Code Playgroud)
我知道它并不重要(除了一些特殊情况),这就是为什么我宁愿在代码设计上征求意见,而不是让它起作用,什么不起作用.
如果您需要一个特定的问题可以使用:什么方式可以产生一个漂亮而一致的代码设计,并且一个人具有(dis)优势而不是另一个?
编辑:不要忘记问题的第二部分.构造函数体中的变量怎么样?
这部分是一个风格问题,部分是一个正确性问题。提交以下示例(处理包含嵌入标头的数据块的类的精简):
class Foo {
public:
Foo(size_t size)
: scratch_(new uint8_t[header_length_ + size]),
size_(header_length_ + size) {
}
~Foo() {
delete[] scratch_;
}
Foo(const Foo&) = delete; // Effective C++
void operator=(const Foo&) = delete; // Effective C++
protected:
struct Header {
uint32_t a, b, c, d;
};
uint8_t * const scratch_;
size_t const size_;
Header * const header_ = reinterpret_cast<Header *>(scratch_);
static constexpr size_t header_length_ = sizeof(Header);
static constexpr size_t data_offset_ = header_length_;
size_t const data_length_ = size_ - data_offset_; …Run Code Online (Sandbox Code Playgroud)