我在书中发现了一句话:
声明它时,不必初始化静态成员;如果不这样做,C ++将调用默认构造函数。
这让我很困惑这意味着什么。他们只谈论对象成员吗?如果是这样,它会在什么时候调用默认构造函数?另外,如何在没有默认构造函数的情况下初始化静态成员对象?
答案 0 :(得分:12)
让我们分解吧。假设在某个地方有一些class Foo;
。现在我们将它作为我们类的静态成员
class Star
{
static Foo z;
// ...
};
现在本质上声明了一个全局对象Foo Star::z
- 那么它是如何实例化的呢?标准告诉你:它得到默认构造。但请记住,您必须在一个翻译单元中提供实际的对象实例:
// in, say, star.cpp
Foo Star::z; // OK, object lives here now
现在假设Foo
实际上没有默认构造函数:
class Foo
{
public:
Foo(char, double); // the only constructor
// ...
};
现在有一个问题:我们如何构建Star::z
?答案是“就像上面一样”,但现在我们必须调用一个特定的构造函数:
// again in star.cpp
Foo Star::z('a', 1.5);
该标准实际上有两个不同的概念,即“初始化”(语法概念)和“构造”(函数调用),但我认为我们现在不需要进入子>
答案 1 :(得分:2)
在C ++中,新对象总是以某种方式初始化。有默认的初始化,复制初始化,值初始化和直接初始化,唯一的问题是你的代码使用的是哪一个。
我认为他们的意思是:
SomeObject SomeClass::x; // default initialization, class types will have the default constructor called
VS
SomeObject SomeClass::x = blah; // copy initialization
需要复制构造函数,在调用复制构造函数之前可能还会将blah
转换为临时SomeObject
,有时会跳过对复制构造函数的调用,但它必须是可访问的
如果您不想调用默认或复制构造函数,请使用直接初始化语法:
SomeObject SomeClass::x(blah); // direct initialization
答案 2 :(得分:1)
修改:移动评论以回答。
根据定义,成员始终是对象成员,因为它表示声明的变量是对象的成员。这就是说静态成员需要向前声明,并且显式初始化变量通常是一种好习惯。这是什么书?
// SomeObject.h
class SomeObject
{
public:
SomeObject(); // default constructor
private:
// declare members
int m_intMember;
static int m_staticIntMember;
};
// SomeObject.cpp
#include "SomeObject.h"
// forward declaration and initializing of static member
int SomeObject::m_staticIntMember(42);
SomeObject::SomeObject() : m_intMember(7) // initializing other member
{
}
答案 3 :(得分:1)
在此声明中: "在声明静态成员时,您不必初始化静态成员;如果你不这样做,C ++将调用默认的构造函数。" "静态成员"是指静态成员"一些原始类型的成员变量,换句话说,"静态成员"的数据类型。应该只是:int,float或char ..... 因此,对于这些原始类型,编译器知道它们的"默认构造函数",例如对于" int"类型,编译器只设置0。 但是如果这些静态成员类型是特定的类,而不是那些C ++内置的基本类型,则必须明确地调用特定的构造函数,它与" Kerrek SB"提供的第一个答案完全相同。 但请记住一件事,即使你的静态成员类型是原始类型,你仍然需要在* .c文件中声明它的实现。 假设在" Kerrek SB"提供的示例中,如果我们更改:
class Star
{
static Foo z;
// ...
};
到
class Star
{
static int z;
// ...
};
// again in star.cpp
int Star::z;
它将被编译器初始化为0;所以我相信"静态成员"在 在"您不必初始化静态成员"只意味着"静态成员"其类型是C ++原始类型。如果它的类型是某些类,则必须将它们的特定构造函数调用为与任何其他类相同的类。对象。