请先查看以下代码:
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;
}
我想知道为什么上面的语句编译发生错误? ?
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> >());
C ++ Primer 5th(第7.5章)中引用的相应知识如下:
我们经常(但不总是)忽略成员是初始化还是分配成员之间的区别。必须初始化const或引用的成员。类似地,也必须初始化具有未定义默认构造函数的类类型的成员
首先,我将分享我的想法。'data'成员在构造函数体开始执行之前默认初始化。对?那么,构造函数中的'data'成员将复制从函数make_shared.right创建的对象?
答案 0 :(得分:4)
第一个编译成功,因为您在成员初始化列表中初始化 data ,这样的语法在这里完全有效。查看this了解详情。
第二个等于 data(...)。它不是 data 对象的构造,编译器将其视为为已创建的 data 成员调用 operator()的尝试(并在错误消息中说明了这一点。
最后在 main 函数中,您只需使用 shared_ptr 复制构造函数从 shared_ptr 创建数据 make_shared
答案 1 :(得分:0)
如果由于多种原因想要稍后初始化数据对象,可以在StrBlob初始化列表和StrBlob构造函数的主体中使用 std :: shared_ptr 默认构造函数 - reset < / strong>功能:
StrBlob::StrBlob()
: data()
{
data.reset(new std::vector<std::string>());
}