C ++ shared_ptr不提供调用运算符

时间:2019-08-23 09:49:05

标签: c++ constructor shared-ptr smart-pointers

我有一个类Foo,其中包含类shared_ptr的{​​{1}}作为成员变量。我是这样宣告上述观点的:

Foo2

首先,我可以执行以上操作吗?即不初始化shared_ptr?

class Foo{ public: Foo(); private: shared_ptr<Foo2> f2; }; 的默认构造函数中,我正在初始化以下shared_ptr变量:

Foo

由于Foo2的唯一构造函数具有3个参数。但是,这显示了错误:

Foo::Foo(){ //create and calculate parameters a, b and c f2(new Foo2(a, b, c)); }

这不是创建类的共享指针实例的方法吗?

6 个答案:

答案 0 :(得分:7)

如果仅在构造函数中创建abc,则必须重新分配f2。您不能在变量的声明或成员初始值设定项列表之外进行初始化(这是您试图执行的操作)。

其中任何一个都可以工作:

f2.reset(new Foo2(a, b, c));
f2 = std::shared_ptr<Foo2>(new Foo2(a, b, c));
f2 = std::make_shared<Foo2>(a, b, c);

答案 1 :(得分:2)

  

a,b和c是在Foo()本身中创建的变量

然后使用赋值运算符:

Foo::Foo() {
    f2 = std::make_shared<Foo2>(a, b, c);
}

答案 2 :(得分:0)

这是您想要做的:

Foo::Foo() : f2(make_shared<Foo2>(a, b, c)) {
}

您看到的错误消息表示您使用的语法试图调用Foo::operator()(A,B,C),即对象上的调用运算符。但是,在初始化期间,该语法会改为调用构造函数。

如果您坚持不初始化f2,也可以这样做:

Foo::Foo() : f2(nullptr) {
   f2 = make_shared<Foo2>(a, b, c);
}

请注意,: f2(nullptr)部分不是严格必需的。我包括了它,以显示默认情况。

答案 3 :(得分:0)

通过执行f2(...);您将operator()方法称为f2.operator()(...); 您需要做的是在initializer list

中初始化指针
Foo::Foo()
: f2(new Foo2(a, b, c))
{}

或使用std::make_shared在构造函数主体中创建它(此方法隐藏了新的运算符)

Foo::Foo()
{
f2 = std::make_shared<Foo2>(a, b, c);
}

答案 4 :(得分:0)

您的构造函数实现不正确。

Foo::Foo(){
//create and calculate parameters a, b and c
f2(new Foo2(a, b, c));
}

语句f2(new Foo2(a, b, c))不会初始化成员f2。它会像使用函数一样尝试使用它(例如,调用接受operator()的{​​{1}})。编译错误是因为Foo2 *没有这样的运算符。

您的构造函数的更正确实现是使用初始化程序列表

std::shared_ptr<Foo2>

这假设Foo::Foo(): f2(new Foo2(a, b, c)) { } ab事先已声明(以编译器可见的方式)并已初始化。

如果在构造函数主体中初始化了cab,那么您需要这样做

c

实际上等同于

Foo::Foo()
{
   //  define and initialise a,b,c
   f2 =  std::make_shared<Foo2>(a, b, c);
}

在上述两种形式中,Foo::Foo() : f2() { // define and initialise a,b,c f2 = std::make_shared<Foo2>(a, b, c); } 的默认构造函数(不接受任何参数)在输入f2构造函数的块之前被调用/调用。语句Foo构造另一个对象并执行移动初始化(假定f2 = std::make_shared<Foo2>(a, b, c)已经构造),而不是初始化。

答案 5 :(得分:0)

当需要先计算abc时,在initializer_list中初始化它的替代方法:

  • 使用直接调用的lambda(可能也是自由功能)

    Foo::Foo() : f2([]()
        {
            //create and calculate parameters a, b and c
            return std::make_shared<Foo2>(a, b, c);
        }())
    {}
    
  • 委托构造函数

    Foo::Foo() : Foo(ComputeABC()) {}
    
    Foo::Foo(std::tuple<int, int, int> t) :
        f2(std::make_shared<Foo2>(std::get<0>(t),
                                  std::get<1>(t),
                                  std::get<2>(t)))
    {}