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

c++ shared_ptr does not provide a call operator

本文关键字:调用 运算符 shared ptr C++      更新时间:2023-10-16

我有一个类Foo,其中包含类Foo2shared_ptr作为成员变量。我这样声明上述判决:

class Foo{
public:
Foo();
private:
shared_ptr<Foo2> f2;
};

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

Foo的默认构造器中,我正在初始化这个shared_ptr varaibale 如下所示:

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

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

Type 'shared_ptr<Foo2>' does not provide a call operator

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

如果仅在构造函数中创建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);

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

然后使用赋值运算符:

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

通过执行 f2(...(; 你调用 operator(( 方法作为f2.operator()(...);您需要做的是在初始值设定项列表中初始化指针

Foo::Foo()
: f2(new Foo2(a, b, c))
{}

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

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

这是你想要做的:

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)部分不是绝对必需的。我包含它是为了显示默认情况下发生了什么。

构造函数实现不正确。

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

语句f2(new Foo2(a, b, c))不初始化成员f2。 它尝试将其用作函数(例如,调用接受Foo2 *operator()(。 编译错误是因为std::shared_ptr<Foo2>没有这样的运算符。

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

Foo::Foo(): f2(new Foo2(a, b, c))
{
}

这假定abc是预先声明的(以编译器可见的方式(并初始化的。

如果在构造函数主体中初始化了abc,那么你需要做

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)构造另一个对象并执行移动赋值(假定f2已经构造(而不是初始化。

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)))
    {}