2009-06-11 2 views
2

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

Каждого переменный (локальный, глобальный, staic, член и не член) гарантировано иметь его т е р Вызываются перед первым использованием

Кортики примитивов, таких как int, по существу, не являются операциями, поэтому мы явно назначаем значение, но по умолчанию нет нулевого значения.

следующие классы семантически одинаковы (и должен генерировать идентичный код)

class A 
{ 
    int n; 
}; 

и

class A 
{ 
    int n; 
public: 
    A() : n() {} 
}; 

и

class A 
{ 
    int n; 
public: 
    A() { n = int(); } 
}; 

Переменная п в каждом случае по-прежнему неинициализированным ,

EDIT:

Казалось, что я absolutetly недооценивать сложность этого вопроса, большинство моих предположений были неправы. Теперь я все еще пытаюсь выяснить основные правила инициализации объекта.

ответ

3

Вы можете найти this интересное.

Разница между новым Foo и новым Foo() является то, что бывшим будет неинициализированными и последним будет по умолчанию инициализируется (до нуля), когда Foo типа POD. Таким образом, если не используется формы с скобками, член «а» может содержать мусор, но с круглыми скобками «а» всегда будет инициализирован 0.

+1

Я считаю, что это утверждение трудно поверить. class Bar {int n; } является POD, поскольку он неявно определен ctor is/trivial/(формальный термин из ISO). Тем не менее, он существует, и оба 'new Bar;' и 'new Bar()' называют это. В любом случае Bar :: Bar() не инициализирует Bar :: n – MSalters

+0

"class B {int n;};" is * not * a POD, поскольку он содержит частный нестатический член 'n'. Однако, если он был определен как «класс B {public: int n;};" то это будет POD, и поэтому «n» будет инициализироваться значением, когда вы будете «new Bar()». –

+1

Возможно ли, чтобы новичок полностью понял эту тему? Кажется, что существует так много правил и исключений :-( – codymanix

4

Боюсь, вы ошибаетесь. Когда вы говорите:

int n = int(); 

Тогда n (и все другие типы POD) инициализируется нолем.

Кроме того, убедитесь, что вы очень ясно в вашем уме о разнице между инициализацией и назначением - это очень важно, в C++:

int n = int(); // initialisation 
n = 0;   // assignment 
1

Нет, переменный только левой неинициализированной в первом случае.

Для члена, который является классом с определяемым пользователем конструктором, ситуация проста: всегда вызывается конструктор.

Встроенные типы (и структуры «простых старых данных») могут быть оставлены неинициализированными, как в первом примере. Хотя они не имеют созданных пользователем конструкторов, использование синтаксиса конструкции (два других примера) инициализирует их до нуля.

Причина этого слегка сложного правила заключается в том, чтобы избежать чрезмерных накладных расходов; Например, если вы определили:

struct S 
{ 
    int array[1024*1024]; 
}; 

с целью только присвоение значений, как вам они нужны, вы не хотели бы, чтобы компилятор обелить 4Мбы памяти нулей всякий раз, когда вы строите один.

+0

Это очень сложно, это намного сложнее, чем я думал. Если я создам пустой ctor A() {}, тогда переменная n инициализируется! Я всегда думал, что когда у вас есть пустой ctor, это то же самое, что и не иметь ctor (какая импликация создаст по умолчанию ctor), поэтому мои 1-й и 4-й классы должны быть одинаковыми, но это не так. – codymanix

+0

Это звучит неправильно. Используете ли вы старую версию GCC? Кроме того, вы должны указать, где вы создаете экземпляр A: я предполагаю на стек или кучу. Если это статический объект, члены будут инициализированы до нуля до вызова конструктора (это называется " инициализация значения ", если вы хотите, чтобы Google для него). –

1
class A 
{ 
    int n; 
}; 

Расположена только память, не выполнена инициализация для n.


class A 
{ 
    int n; 
public: 
    A() : n() {} 
}; 

Здесь n инициализируется 0.


class A 
{ 
    int n; 
public: 
    A() { n = int(); } 
}; 

Здесь n сначала сконструированной (без стоимости любого по умолчанию), то int() вызывает временную Int быть созданный со значением 0 , который затем присваивается n;

+0

Очень странно. Я был уверен, что однажды у меня была вторая версия с A(): n() {} в моем проекте, и это вызвало n не инициализацию .Я использовал GCC, хотя. Может ли это быть зависимым от компилятора? – codymanix

+0

@codymanix. Нет, это стандартное поведение. Хотя я верю в первую версию стандарта, это не было указано, потому что кто бы это сделал !!! Поэтому ваши наблюдения могут быть верны для очень старого компилятора. –

Смежные вопросы