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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7368330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:49:50  来源:igfitidea点击:

Static members and the default constructor C++

c++constructorstatic-members

提问by rubixibuc

I came across a statement in my book that said:

我在我的书中看到了一个声明,它说:

You don't have to initialize a static member when you declare it; C++ will invoke the default constructor if you don't.

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

This really has me confused as to what it means. Are they talking about object members only? If so, at what point would it call the default constructor? Also, how would you initialize a static member object without the default constructor?

这真的让我对它的含义感到困惑。他们只是在谈论对象成员吗?如果是这样,它会在什么时候调用默认构造函数?另外,如果没有默认构造函数,您将如何初始化静态成员对象?

回答by Kerrek SB

Let's break it down. Suppose there's some class Foo;somewhere. Now we make this a static member of our class,

让我们分解一下。假设class Foo;某处有一些。现在我们使它成为我们类的静态成员,

class Star
{
  static Foo z;
  // ...
};

Now in essence that declares a global object Foo Star::z-- so how does this get instantiated? The standard tells you: it gets default-constructed. But remember that you have to provide the actual object instance in one of your translation units:

现在本质上声明了一个全局对象Foo Star::z——那么它是如何被实例化的呢?标准告诉你:它是默认构造的。但请记住,您必须在其中一个翻译单元中提供实际的对象实例:

// in, say, star.cpp
Foo Star::z;  // OK, object lives here now



Now suppose that Foodoesn't actually have a default constructor:

现在假设它Foo实际上没有默认构造函数:

class Foo
{
public:
  Foo(char, double); // the only constructor
  // ...
};

Now there's a problem: How do we construct Star::z? The answer is "just like above", but now we have to call a specific constructor:

现在有一个问题:我们如何构建Star::z?答案是“就像上面一样”,但现在我们必须调用一个特定的构造函数:

// again in star.cpp
Foo Star::z('a', 1.5);


The standard actually has two distinct notions of "initialization" (a grammatical concept) and "construction" (a function call), but I don't think we need to go into this just now.


该标准实际上有两个不同的概念,即“初始化”(一个语法概念)和“构造”(一个函数调用),但我认为我们现在不需要讨论这个。

回答by Ben Voigt

In C++, new objects are always initialized somehow. There's default initialization, copy initialization, value initialization, and direct initialization, the only question is which one your code is using.

在 C++ 中,新对象总是以某种方式初始化。有默认初始化、复制初始化、值初始化和直接初始化,唯一的问题是您的代码使用的是哪一种。

I assume they mean:

我假设他们的意思是:

SomeObject SomeClass::x; // default initialization, class types will have the default constructor called

vs

对比

SomeObject SomeClass::x = blah; // copy initialization

The copy constructor is needed, possibly there's also a conversion of blahto a temporary SomeObjectbefore calling the copy constructor, and sometimes the call to the copy constructor is skipped, but it must be accessible.

需要复制构造函数,在调用复制构造函数之前可能还有blah一个临时转换SomeObject,有时会跳过对复制构造函数的调用,但它必须是可访问的。

If you don't want to call the default or copy constructor, use direct initialization syntax:

如果不想调用默认或复制构造函数,请使用直接初始化语法:

SomeObject SomeClass::x(blah); // direct initialization

回答by AJG85

Edit:Moving the comment to answer.

编辑:移动评论来回答。

memberis by definition always an object memberas it means a declared variable as a member of an object. That said static members need to be forward declared and it's generally good practice to explicitly initialize variables. What book is this?

构件是通过定义一个总是对象构件,因为它意味着一个声明的变量作为对象的成员。也就是说,静态成员需要前向声明,并且显式初始化变量通常是一种很好的做法。这是什么书?

// 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
{
}

回答by Clock ZHONG

In this statement: "You don't have to initialize a static member when you declare it; C++ will invoke the default constructor if you don't." "The static member" means the "static member" of some primitive types member variable, in another word, the data types of the "static member" should only be: int, float, or char..... So for these primitive types, compiler know their "default constructor", e.g. for the "int" type, compiler just set 0. But if these static members types are specific classes, not those C++ built-in primitive types, you must call the specific constructor function explicitly, it's exactly same as the 1st answer provided by "Kerrek SB" But remember one thing, even your static member's type is primitive type, you still need declare its implementation in the *.c file. Assume in the example provided by "Kerrek SB", if we change the:

在这个声明中:“当你声明一个静态成员时,你不必初始化它;如果你不这样做,C++ 将调用默认构造函数。” “静态成员”是指某些原始类型成员变量的“静态成员”,换句话说,“静态成员”的数据类型应该只有:int、float或char……所以对于这些原始类型类型,编译器知道它们的“默认构造函数”,例如对于“int”类型,编译器只设置 0。但是如果这些静态成员类型是特定的类,而不是那些 C++ 内置基本类型,则必须显式调用特定的构造函数,它与“Kerrek SB”提供的第一个答案完全相同但请记住一件事,即使您的静态成员的类型也是原始类型,您仍然需要在 *.c 文件中声明它的实现。假设在“Kerrek SB”提供的例子中,如果我们改变:

class Star
{
  static Foo z;
  // ...
};

to

class Star
{
  static int z;
  // ...
};

in the star.h file, we still need to add one line in star.c as:

在star.h文件中,我们仍然需要在star.c中添加一行:

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

It'll be initialized as 0 by compiler; So I believe the "static member" in in "You don't have to initialize a static member" only means "static member" whose type is C++ primitive type. If its type are some classes, you must call their specific constructor function as same as any other classes' objects.

它会被编译器初始化为 0;所以我认为“您不必初始化静态成员”中的“静态成员”仅表示类型为C++原始类型的“静态成员”。如果它的类型是一些类,你必须像调用任何其他类的对象一样调用它们特定的构造函数。