2014-11-12 2 views
2

Я довольно новыми для C++, написал пример кода:Должен ли T() инициализировать переменные-члены до нуля?

#include <iostream> 

class Point 
{ 
public: 
    int X, Y; 

    int dis() 
    { 
     std::cout << X << Y << std::endl; 
     return X; 
    } 

    int operator=(const Point&) 
    { 
     int dat = 3; 
     return dat; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Point p2 = Point(); 
    p2.dis(); 
    return 0; 
} 

Здесь p2 должны инициализировать оба класса Point переменные x и y к нулю правильно? Но вместо этого, когда я делаю p2.dis(), я получаю x и y, проиндексированные на случайные значения.

и в следующем случае tSum = 0, даже если «T» имеет тип класса.

template<typename T> 
double GetAverage(T tArray[], int nElements) 
{ 
    T tSum = T(); // tSum = 0 
    for (int nIndex = 0; nIndex < nElements; ++nIndex) 
    { 
     tSum += tArray[nIndex]; 
    } 

    // Whatever type of T is, convert to double 
    return double(tSum)/nElements; 
} 

как это отличается?

Заранее благодарим за разъяснения.

+0

Где находятся шаблоны? Вы никогда не используете 'Item'. Как указано, код должен работать, как вы его описываете. –

+0

Вы можете использовать ** в инициализаторах класса **, чтобы сделать ваш код более удобочитаемым. Затем, если значение не та, которую вы установили, вам нужно будет только искать место, где значения по умолчанию переопределены. –

+1

У VC++ есть некоторые ошибки, связанные с инициализацией значений. –

ответ

4

Правила языка требует

Point p2 = Point(); 

на значение инициализацииp2. Поскольку Point не имеет определяемого пользователем конструктора, инициализация значения включает в себя нулевую инициализацию и оба значения: p2.X и p2.Yshould be zero.

Вы видите ошибку Visual C++ (-858993460 - 0xCCCCCCCC, которая VC++ заполняет неинициализированные переменные в режиме отладки). Обходной путь заключается в предоставлении конструктора по умолчанию Point, который явно инициализирует обе переменные-члены равными нулю.

+0

Я согласен, может быть ошибкой visualC++. – rahul

+0

Просто любопытно: «Point p2 = Point()» означает инициализацию по умолчанию ('Point()'), что означает инициализацию по умолчанию для своих нестатических элементов данных, которые для целых чисел инициализируются инициализацией по значению, за которыми следует копирование-инициализация для 'p2'? – 0x499602D2

+1

@ 0x499602D2 'Point()' инициализация значения, а не инициализация по умолчанию. Pre-C++ 11 означает инициализацию значений элементов данных, которые для 'int' означают нулевую инициализацию; post-C++ 11 этот нуль инициализирует 'Point'. Все это создает инициализированное значение, а затем копирует-инициализирует 'p2', но временное исключается в любом достойном компиляторе. –

2

Вам просто нужно конструктор со значениями по умолчанию для обоих полей:

Point() : X(), Y() 
{ 
} 
+0

Примечание: это должно работать, даже в C++ 98 –

0

В C++ 98 этот код оставляет p2.X и p2.Y неинициализирован.

Это потому, что Point имеет оператор копирования назначения пользователя объявленная, поэтому Point является то, что известно как не-POD класса.

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

В инициализации C++ 03 была проведена большая переделка и введена инициализация значения . Point() был теперь инициализацией значения, что означает, что конструктор по умолчанию называется , только если он был объявлен пользователем.

Если вы не объявили конструктор по умолчанию, то члены класса инициализируются значением, даже если класс не является POD. Таким образом, p2.X и p2.Y должны быть инициализированы до 0 в C++ 03 (и позже).


Nowdays мы хотели бы делать вид C++ 98 никогда не существовало, но, видимо MSVC++ все еще следует за ним в некоторых случаях инициализации. (Последние версии 32-битного C++ Builder также используют и инициализацию в стиле C++ 98).

+0

Было бы интересно узнать, выполняет ли инициализация MSVC++ при инициализации нуля, если вы удаляете свой оператор присваивания копий (что указывает C++ 98 - POD имеют члены с нулевым инжинирингом). –

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