C++构造函数理解
C++ Constructor Understanding
考虑这个构造函数:Packet() : bits_(0), datalen_(0), next_(0) {}
注意,bits_
、datalen_
和next_
是分组类中的字段,定义如下:
u_char* bits_;
u_int datalen_;
Packet* next_;
构造函数的这一部分是什么意思?bits_(0), datalen_(0), next_(0)
这是一个初始值设定项列表,它将值设置为指定的值。
Packet() : bits_(0), datalen_(0), next_(0)
{
assert( bits_ == 0 );
assert( datalen_ == 0);
assert( next_ == 0);
}
//...
Packet()
{
//bits_ , datalen_, next_ uninitialized here
}
某些成员(const
成员或没有默认构造函数的用户定义类成员)无法在初始值设定项列表之外进行初始化:
class A
{
const int x;
A() { x = 0; } //illegal
};
class A
{
const int x;
A() : x(0) { } //legal
};
还值得一提的是,使用这种技术不会发生双重初始化:
class B
{
public:
B() { cout << "default "; }
B(int) { cout << "b"; }
};
class A
{
B b;
A() { b = B(1); } // b is initialized twice - output "default b"
A() : b(1) { } // b initialized only once - output "b"
};
这是初始化成员的首选方式。
这意味着首先bits_,然后datalen_和最后next_ 这个: 不过要小心。初始化顺序由成员声明顺序决定。也就是说,以下代码无法按预期工作: 它将相当于: 因此第二个将收到一个0,但第一个Packet()
: bits_(0)
, datalen_0)
, next_(0)
{
}
Packet()
{
bits_ = 0;
datalen_ = 0;
next_ = 0;
}
struct Packet
{
int first;
int second;
Packet()
: second(0)
, first(second)
{
}
};
struct Packet
{
int first;
int second;
Packet()
{
first = second;
second = 0;
}
};
它被称为初始化器列表,它用括号中指定的值初始化字段。以下将实现相同的最终效果:
Packet()
{
bits_ = nullptr; // or 0 or NULL pre-C++11
datalen_ = 0;
next_ = nullptr;
}
不同的是,在我的例子中,你正在进行赋值,字段已经由它们的默认构造函数构造了。
对于没有默认构造函数的用户定义类型,初始值设定项列表是唯一的方法,因为您需要向构造函数提供一些参数。
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为