C ++中的构造函数初始化列表

时间:2016-10-25 05:26:54

标签: 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<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创建的对象?

2 个答案:

答案 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>());
}