C++ 在C+;中为构造函数使用初始值设定项有什么好处+;?
为什么使用初始化器(上面)编写的构造函数比使用在其主体(下面)中初始化数据成员的构造函数更可取C++ 在C+;中为构造函数使用初始值设定项有什么好处+;?,c++,C++,为什么使用初始化器(上面)编写的构造函数比使用在其主体(下面)中初始化数据成员的构造函数更可取 如果不显式初始化字段,编译器将尝试运行这些字段的默认构造函数。如果它们没有可访问的默认构造函数,则源代码将无法编译: Sphere() { theRadius = 1.0; } 如果它们确实有一个默认构造函数,则在调用正文中字段的另一个构造函数时,不必要地调用它。,因为否则会调用对象的默认构造函数,然后设置值 这将只调用字符串构造函数 class Field { public: F
如果不显式初始化字段,编译器将尝试运行这些字段的默认构造函数。如果它们没有可访问的默认构造函数,则源代码将无法编译:
Sphere()
{
theRadius = 1.0;
}
如果它们确实有一个默认构造函数,则在调用正文中字段的另一个构造函数时,不必要地调用它。,因为否则会调用对象的默认构造函数,然后设置值 这将只调用字符串构造函数
class Field {
public:
Field(int x) {}
};
class Test {
Field f;
public:
Test() { // compiler error here. `Field` doesn't have default constructor.
f = Field(10);
}
};
int main ( ) {
Test t;
}
其中:
class Foo{
std::string s;
Foo() : s("Hello World"){}
}
将调用默认的字符串构造函数,然后将字符串的值设置为“Hello World”所有成员在进入构造函数体之前都会进行初始化。如果在init列表中没有提供初始化器,那么它们是默认构造的 在第一个示例中,会发生以下情况:
已初始化为1.0theRadius
已初始化theRadius
- 1.0复制到
theRadius
operator=
更改该值
这可能不是你想要的。
特别是,您不能在构造函数体中更改const
属性的值。
您必须使用init列表。如前所述,对于非原语类型,它会有所不同 这也是初始化常量成员变量的唯一方法
class Foo{
std::string s;
Foo(){
s = "Hello World";
}
}
这不应该编译。就像其他人所说的,对于具有非平凡结构的类型,使用第一种形式更有效 此外,第一种形式使您能够捕获成员对象(或基类)的构造函数中抛出的任何异常,该成员对象(或基类)正在使用try/catch块的函数形式进行初始化。e、 g:
class MyClass
{
const int x;
public:
MyClass(int x)
{
this->x=x;
}
};
这并不缺少一组括号。如果在try/catch块周围放置另一组括号,则它不会捕获memberObject构造函数中的异常,只捕获try块。它主要用于初始化常量和引用变量,因为它们无法在构造函数体中初始化。答案很好,但我也要提到,在当前C++中初始化器也有缺点(我认为它们在C++ 0x中固定了,在那里你可以调用其他构造函数)。如果您碰巧有一个包含多个构造函数的类,那么您可能会得到重复的初始值设定项列表。调用一些常见的init函数可以修复这种重复,但会失去效率。另一个值得一提的问题是(缺少)初始化顺序-在构造具有依赖关系的对象时,如引用“父”对象进行初始化时,您必须注意它。@MaR,如果我有多个构造函数,我可以接受重复。此外,也不缺少初始化的顺序。初始化顺序非常明确。变量总是按照在类定义中声明的顺序进行初始化。这是由C++标准规定的。我记不起章节号了,但它在年的asnwers中被引用了很多次SO@Glen-这就是为什么“缺少”在括号中的原因:o)有一个顺序,但您必须注意它(顺序在类定义中(不同的地方!),并且它不是语法错误),而非初始值设定项代码实际上是显式的。@MaR,我明白您的意思了。然而,这句话“另一个值得一提的问题是(缺少)初始化顺序”读起来就像你说没有初始化顺序一样。把它放在括号里并不是你想表达的意思
class MyClass
{
const int x;
public:
MyClass(int x)
{
this->x=x;
}
};
MyObject() : memberObject(...)
try {
// my constructor
}
catch (...) {
// catches exceptions in try block AND memberObject constructor
}