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+中的构造函数初始值设定项列表+;_C++_C++11_Initializer - Fatal编程技术网

C++ C+中的构造函数初始值设定项列表+;

C++ C+中的构造函数初始值设定项列表+;,c++,c++11,initializer,C++,C++11,Initializer,请先查看以下代码: class StrBlob { public: StrBlob(); // .... private: std::shared_ptr<std::vector<std::string> > data; } //initializer empty into data ; StrBlob::StrBlob() // : data(std::make_shared<std::vector

请先查看以下代码:

class StrBlob
{
    public:
        StrBlob();
        // ....
    private:
        std::shared_ptr<std::vector<std::string> > data;
}
//initializer empty into data ;

StrBlob::StrBlob()
// : data(std::make_shared<std::vector<std::string> >())      // compile success
{
 //  data(std::make_shared<std::vector<std::string> >());     // compile error
}
int main()
{
    // this statement can compile
    std::shared_ptr<std::vector<std::string> >data(std::make_shared<std::vector<std::string> >());
    return 0;
}
类StrBlob
{
公众:
StrBlob();
// ....
私人:
std::共享的ptr数据;
}
//初始化器清空数据;
StrBlob::StrBlob()
//:data(std::make_shared())//编译成功
{
//数据(std::make_shared());//编译错误
}
int main()
{
//此语句可以编译
std::shared_ptrdata(std::make_shared());
返回0;
}
我想知道为什么上面的语句编译出现错误

error: no match for call to ‘(std::shared_ptr<std::vector<std::__cxx11::basic_string<char> > >)
   (std::shared_ptr<std::vector<std::__cxx11::basic_string<char> > >)’
   data(std::make_shared<std::vector<std::string> >());
错误:调用(std::shared_ptr)不匹配
(标准::共享_ptr)'
数据(std::make_shared());
C++初级读物5(第7.5章)中引用的相应知识如下:

我们可以经常(但并非总是)忽略成员是初始化还是分配的区别。必须初始化常量或引用的成员。类似地,属于未定义默认构造函数的类类型的成员也必须初始化


首先,我将分享我的想法。在构造函数体开始执行之前,“data”成员是默认初始化的。正确的?因此,构造函数中的“data”成员将复制从函数make_shared创建的对象。对吗

第一个编译成功,因为您初始化了成员初始值设定项列表中的数据,并且这种语法在这里完全有效。查看更多信息

第二个等于数据(…)。它不是数据对象的构造,编译器将其视为对已创建的数据成员调用运算符()的尝试(并在错误消息中说明)


最后,在main函数中,您只需使用shared_ptr copy构造函数从make_shared返回的shared_ptr创建数据。

第一个函数编译成功,因为您在成员初始值设定项列表中初始化了数据,并且这种语法在这里完全有效。查看更多信息

第二个等于数据(…)。它不是数据对象的构造,编译器将其视为对已创建的数据成员调用运算符()的尝试(并在错误消息中说明)


最后,在main函数中,您只需使用shared_ptr copy构造函数从make_shared返回的shared_ptr创建数据。

如果出于多种原因以后要初始化数据对象,您可以在StrBlob初始化列表和StrBlob构造函数的主体中使用std::shared_ptr默认构造函数-重置函数:

StrBlob::StrBlob()
 : data()
{
   data.reset(new std::vector<std::string>());
}
StrBlob::StrBlob()
:data()
{
data.reset(新的std::vector());
}

如果出于多种原因希望稍后初始化数据对象,可以在StrBlob初始化列表和StrBlob构造函数主体中使用std::shared_ptr默认构造函数-重置函数:

StrBlob::StrBlob()
 : data()
{
   data.reset(new std::vector<std::string>());
}
StrBlob::StrBlob()
:data()
{
data.reset(新的std::vector());
}

因为您无法在构造函数体内部构造/初始化这样的对象。它只允许在初始值设定项列表中使用。你可以分配给已经在体内的已经构建的对象,但是“你可以分配给已经在体内的已经构建的对象”,但是你不应该在C++代码中养成习惯,因为你不能在构造函数的主体中构建/初始化像这样的对象。它只允许在初始值设定项列表中使用。你可以分配给已经在体内的已经构建的对象。“你可以指派已经在体内的已经构建的对象”,但是你不应该在C++代码中养成习惯。我认为我们应该避免这样的结构,因为这个代码不是最佳的。例如,参见迈尔斯的书。@Edgarokyan这是一个简单的例子。实际上,不能总是在初始化列表中初始化对象,因为有时需要计算一些输入参数。关于效率,我只调用默认构造函数和重置函数。我创建了一次向量对象。我不怀疑你的答案。事实上,我同意这一点。我的帖子的目的是展示另一种解决方案。我认为我们应该避免这种构造,因为这种代码不是最优的。例如,参见迈尔斯的书。@Edgarokyan这是一个简单的例子。实际上,不能总是在初始化列表中初始化对象,因为有时需要计算一些输入参数。关于效率,我只调用默认构造函数和重置函数。我创建了一次向量对象。我不怀疑你的答案。事实上,我同意这一点。我的帖子的目的是展示另一个解决方案。你说得对。第二个数据(..)是调用复制构造函数?但是数据对象已经在调用数据(..)之前创建。如果是的话。这意味着调用复制构造函数两次。编译时会出现错误。我说的对吗?不,第二个不是复制构造函数调用。它是对
操作符()
的调用,对于您的类来说,它没有重载。这就是它无法编译的原因。在你不同意我的想法之前,我想了一会儿。我试图重载操作符()成员。而且它起作用了。对应编译器给出的错误,我想我知道。祝你万事如意!最后,我想问一下,它是否也可能是错误的,因为调用了两次复制构造函数,只是编译器没有报告错误???@AndyCong我不明白如何调用一个复制构造函数两次。在成员初始值设定项列表中只有一个调用…也许这些是我的观点错误。我想得太多了。因为数据的行为(..)看起来像复制构造函数,我认为问题可以简化如下代码:std::vector vec1,vec2;vec1(vec2);然后第二种说法就是我们讨论的问题。这似乎是复制构造函数的行为吗?你认为呢?我需要你的帮助,你说得对。第二个数据(..)是调用复制构造函数?但是数据对象是