Статические члены и конструктор по умолчанию C ++ - PullRequest
4 голосов
/ 10 сентября 2011

В моей книге я встретил утверждение, в котором говорилось:

Вам не нужно инициализировать статический член при его объявлении; C ++ вызовет конструктор по умолчанию, если вы этого не сделаете.

Это действительно сбивает меня с толку относительно того, что это значит. Они говорят только о членах объекта? Если так, в какой момент он вызвал бы конструктор по умолчанию? Кроме того, как бы вы инициализировали статический объект-член без конструктора по умолчанию?

Ответы [ 4 ]

12 голосов
/ 10 сентября 2011

Давайте разберемся.Предположим, где-то есть 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);


Стандарт фактически имеет два различных понятия «инициализация» (грамматическая концепция)и "конструкция" (вызов функции), но я не думаю, что нам нужно сейчас углубляться в это.

2 голосов
/ 10 сентября 2011

В C ++ новые объекты всегда как-то инициализируются. Есть инициализация по умолчанию, инициализация копирования, инициализация значения и прямая инициализация. Единственный вопрос - какой из них использует ваш код.

Я предполагаю, что они означают:

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

против

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

Необходим конструктор копирования, возможно, есть также преобразование blah во временный SomeObject перед вызовом конструктора копирования, и иногда вызов конструктора копирования пропускается, но он должен быть доступен.

Если вы не хотите вызывать конструктор по умолчанию или конструктор копирования, используйте синтаксис прямой инициализации:

SomeObject SomeClass::x(blah); // direct initialization
1 голос
/ 09 октября 2015

В этом утверждении: «Вам не нужно инициализировать статический член при его объявлении; C ++ вызовет конструктор по умолчанию, если вы этого не сделаете». «Статический член» означает «статический член» некоторой переменной-члена примитивных типов, другими словами, типы данных «статического члена» должны быть только: int, float или char ..... Таким образом, для этих примитивных типов компилятор знает их «конструктор по умолчанию», например, для типа "int" компилятор просто устанавливает 0. Но если эти типы статических членов являются конкретными классами, а не теми встроенными примитивными типами C ++, вы должны явно вызывать конкретную функцию конструктора, это точно так же, как 1-й ответ, предоставленный «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 ++. Если его типом являются некоторые классы, вы должны вызывать их конкретную функцию конструктора так же, как и объекты любых других классов.

1 голос
/ 10 сентября 2011

Редактировать: Перемещение комментария к ответу.

member по определению всегда member object , поскольку это означает объявленную переменную какчлен объекта.При этом статические члены должны быть заранее объявлены, и, как правило, рекомендуется явно инициализировать переменные.Что это за книга?

// 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
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...