Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中初始化引用+; struct C{ std::矢量foo; 康斯特国际律师事务所; C(); }; C::C():条(foo[0]){ foo.推回(5); }_C++_Reference_Initialization - Fatal编程技术网

C++ 在C+中初始化引用+; struct C{ std::矢量foo; 康斯特国际律师事务所; C(); }; C::C():条(foo[0]){ foo.推回(5); }

C++ 在C+中初始化引用+; struct C{ std::矢量foo; 康斯特国际律师事务所; C(); }; C::C():条(foo[0]){ foo.推回(5); },c++,reference,initialization,C++,Reference,Initialization,代码可以编译,但编译后的文件无法运行 这种初始化参考条的方法有什么问题?我认为只要foo在bar之前声明,我们就可以使用foo[0]在构造函数中初始化bar 有人能说出为什么会这样吗 向量处于空状态。初始化列表在括号中的代码之前构造对象,因此您的后推不会影响栏(foo[0])。因此,您的foo[0]正在访问一个空向量,超出了范围 请注意,每当调整大小时,对vector元素的引用都会失效。因此,保留对向量元素的引用是不值得的。因为您的foo未初始化,所以您可以使用初始值设定项列表,将您的foo初始

代码可以编译,但编译后的文件无法运行

这种初始化参考条的方法有什么问题?我认为只要foo在bar之前声明,我们就可以使用foo[0]在构造函数中初始化bar


有人能说出为什么会这样吗

向量处于空状态。初始化列表在括号中的代码之前构造对象,因此您的
后推
不会影响
栏(foo[0])
。因此,您的
foo[0]
正在访问一个空向量,超出了范围


请注意,每当调整大小时,对
vector
元素的引用都会失效。因此,保留对向量元素的引用是不值得的。

因为您的foo未初始化,所以您可以使用初始值设定项列表,将您的foo初始化为条前至少1的大小。这也是c++98的有效版本

struct C{
std::矢量foo;
康斯特国际律师事务所;
C();
};
C::C():foo(1)//初始化大小为1的foo
,bar(foo[0]){
foo[0]=5;//这是保证异常安全的
}
但是你必须注意初始化列表的顺序。它按结构/类中声明的顺序排序。看

根据ISO/IEC 14882:2003(E)第12.6.2节:

初始化应按以下顺序进行:

  • 首先,并且仅针对如下所述的最派生类的构造函数,虚拟基类应按照它们在基类的有向无环图的深度优先的从左到右遍历中出现的顺序进行初始化,其中“从左到右”基类名称在派生类基类说明符列表中的出现顺序
  • 然后,直接基类应按照它们在基说明符列表中出现的声明顺序进行初始化(无论mem初始值设定项的顺序如何)
  • 然后,应按照类定义中声明的顺序初始化非静态数据成员(同样,与mem初始值设定项的顺序无关)
  • 最后,执行构造函数的主体

编辑:
由于Kerrek SB的评论,您无法使用向量。当你推某些东西时,foo会被调整大小(重新分配),而bar会丢失正确的引用。您可以使用
std::deque
或将向量初始化为永远不会传递的特定大小。

这是非常危险的,即使您可以使特定的构造工作正常:向量元素引用通常在您变异向量时无效。为什么不使用不可调整大小的容器?(或者至少是一个
deque
,它不会很容易地使引用无效。)如果我使用一个不可调整大小的容器,问题不会仍然存在,因为我将首先初始化bar(其中foo可以是deque)。是的,当然,您必须先初始化容器,但这很简单:
C::C():foo(100),bar(foo.front()){}
,或者在C++11中,
C::C():foo{1,2,3,4},bar{foo.front()}{}
。您知道如何在bar之前先初始化向量foo吗?就像在我引用它之前先创建foo[0]=5一样?@user22119您使用的是C++11还是C++03?还要注意的是,对向量元素的引用经常会失效。我使用的是旧版本,我认为是C++03。这是一个问题,因为一旦它们被初始化,您就无法更改它们。谢谢,您的答案正好解决了我的问题。我的问题是我不知道如何首先初始化foo。@user22119这将保留1个元素。然后,它会使用推回,它会采取一个保留的位置。在此之后,元素将重新调整大小,引用将有可能无效。尽管这在语法上是正确的,但它仍然是UB,因为
push_back
会使引用无效(缺少适当的
capacity()
检查,您没有这样做).@KerrekSB现在应该可以像预期的那样安全运行了。@T皮特:是的,但它仍然毫无意义,因为你永远无法向向量中添加任何其他内容。。。
struct C{
    std::vector<int> foo;
    const int &bar;
    C();
};

C::C(): bar(foo[0]){
    foo.push_back(5);
}