C++ 必须在构造函数初始化列表中初始化引用类型吗?

C++ 必须在构造函数初始化列表中初始化引用类型吗?,c++,reference,C++,Reference,作为自我锻炼,我编写了以下简单代码: #include <iostream> int gIndex = 3; template <class T> class Array { public: explicit Array(int size); T& operator[](int i) { return m_data[i]; } T operator[](int i) const { return m_data[i]; } T g

作为自我锻炼,我编写了以下简单代码:

#include <iostream>

int gIndex = 3;

template <class T> class Array
{
public:
    explicit Array(int size);
    T& operator[](int i) { return m_data[i]; }
    T operator[](int i) const { return m_data[i]; }
    T getAnchorPoint() const { return m_data[m_anchor]; }
private:
    T* m_data;
    int m_size;
    int& m_anchor;
};

template <class T> Array<T>::Array(int size) : m_size(size), m_data(new T[size])
{
    memset(m_data, 0, size*sizeof(T));
    m_anchor = gIndex;
}

int main()
{
    Array<double> a(10);
    return 0;
}
#包括
int-gIndex=3;
模板类数组
{
公众:
显式数组(int-size);
T&运算符[](int i){返回m_数据[i];}
T运算符[](int i)常量{返回m_数据[i];}
T getAnchorPoint()常量{return m_data[m_anchor];}
私人:
T*m_数据;
国际货币单位大小;
int&m_锚;
};
模板数组::数组(int size):m_size(size),m_数据(新的T[size])
{
memset(m_数据,0,大小*sizeof(T));
m_anchor=gIndex;
}
int main()
{
阵列a(10);
返回0;
}
我得到一个编译错误,上面说:

错误C2758:'Array::m_anchor':必须在构造函数基/成员初始值设定项列表中初始化

这从未发生过,是什么让我问这个问题:

必须在构造函数初始化列表中初始化任何类成员引用类型吗

若然,原因为何?这是否与引用类型永远无法重新分配有关

构造函数初始化列表中还有更多类型必须初始化吗

是否必须在构造函数初始化列表中初始化任何类成员引用类型

若然,原因为何?这是否与引用类型永远无法重新分配有关

这是部分原因。另一部分是因为引用必须初始化,并且它没有默认构造函数

构造函数初始化列表中还有更多类型必须初始化吗

没有赋值运算符(复制或移动)或默认构造函数的任何类型。这显然包括(但不限于)
const
成员,因为一旦构建它们,它们就不能被修改


根据经验,您应该(几乎)总是更喜欢在构造函数的初始化列表中初始化您的成员:当您可以首先正确地构造对象时,为什么先默认构造一个对象,然后只分配给它(如果可能的话)

必须在构造函数初始化列表中初始化任何类成员引用类型吗

这是否与引用类型永远无法重新分配有关

是的,再加上引用没有“null”或默认构造这一事实。它是另一个对象的别名,必须从一开始就绑定到它。不能执行此操作(这不在类定义内):

因为
iref
必须有别名

是的,我们应该始终使用初始值设定项列表来初始化类的引用成员

If so, why? Is that related somehow to the fact that a reference type can never be reassigned?
构造函数有两个阶段,即初始化和计算。所以,即使不为数据成员使用初始值设定项列表,编译器也会使用随机值对其进行初始化。在计算阶段,通常以构造函数体的“{”开头,如果您进行赋值,那么编译器会抱怨引用成员已初始化。因此,初始化此类成员的唯一机会是构造函数初始值设定项列表

Are there more types that must be initialized in constructor initialization list?

是的,const data members是需要初始值设定项列表的另一种类型。

我真的很不好意思问这个问题,但是引用类型没有赋值运算符?@user1798362否,引用它只是其他类型的别名。当你“赋值”时对于引用,您实际上是将其分配给它引用的对象。感谢这个示例,现在我完全明白了!编译器不会因为分配而抱怨(分配给引用实际上是分配给被引用的对象,这没有问题)或者是因为引用已经初始化,但一开始还没有初始化(这是非法的)。
Are there more types that must be initialized in constructor initialization list?
Are there more types that must be initialized in constructor initialization list?