静态成员和默认构造函数C ++

时间:2011-09-09 23:02:47

标签: c++ constructor static-members

我在书中发现了一句话:

  

声明它时,不必初始化静态成员;如果不这样做,C ++将调用默认构造函数。

这让我很困惑这意味着什么。他们只谈论对象成员吗?如果是这样,它会在什么时候调用默认构造函数?另外,如何在没有默认构造函数的情况下初始化静态成员对象?

4 个答案:

答案 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;
  // ...
};
在star.h文件中, 我们仍然需要在star.c中添加一行:

// again in star.cpp
int Star::z;

它将被编译器初始化为0;所以我相信"静态成员"在 在"您不必初始化静态成员"只意味着"静态成员"其类型是C ++原始类型。如果它的类型是某些类,则必须将它们的特定构造函数调用为与任何其他类相同的类。对象。