T()应该将成员变量初始化为零吗?

时间:2014-11-12 21:17:16

标签: c++ visual-c++ initialization

我是C ++的新手,编写了一个示例代码:

#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变量xy初始化为零吗?但是,当我执行p2.dis()时,我会将xy初始化为一些随机值。

并且在以下情况下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;
}

这有什么不同?

提前感谢您的澄清。

3 个答案:

答案 0 :(得分:4)

语言规则要求

Point p2 = Point();

value-initialize p2。由于Point没有用户定义的构造函数,因此值初始化包括零初始化以及p2.Xp2.Y should be zero

您正在看到Visual C ++错误(-858993460是0xCCCCCCCC,VC ++在调试模式下填充未初始化的变量。解决方法是为Point提供一个默认构造函数,将两个成员变量显式初始化为零。

答案 1 :(得分:2)

您只需要两个字段都具有默认值的构造函数:

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

答案 2 :(得分:0)

在C ++ 98中,此代码使p2.Xp2.Y保持未初始化状态。

这是因为Point有一个用户声明的复制赋值运算符,因此Point被称为非POD 类。

在C ++ 98中,非POD类的Point()总是调用默认构造函数(即使隐式声明);并且隐式声明的默认构造函数不会初始化任何类成员。

在C ++ 03中,初始化得到了重大修改,并引入了值初始化Point()现在是值初始化,这意味着默认构造函数只有在用户声明时才被称为

如果您没有声明默认构造函数,那么即使该类是非POD,也会对类成员进行值初始化。因此,必须在C ++ 03(及更高版本)中将p2.Xp2.Y初始化为0


现在我们想假装C ++ 98从未存在,但显然MSVC ++在一些初始化案例中仍然遵循它。 (在这种情况下,C ++ Builder 32位的最新版本也使用C ++ 98样式的初始化。)