c++ shared_ptr 不提供调用运算符
c++ shared_ptr does not provide a call operator
我有一个classFoo
,其中包含classFoo2
的shared_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
这不是创建class的共享指针实例的方法吗?
这就是你想要做的:
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)
部分并非绝对必要。我包含它是为了显示默认情况下发生的情况。
如果a
、b
和c
只在构造函数中创建,则必须重新赋值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 and c are variables that are created in Foo() itself
然后使用赋值运算符:
Foo::Foo() {
f2 = std::make_shared<Foo2>(a, b, c);
}
通过执行 f2(...);您将 operator() 方法调用为 f2.operator()(...);
您需要做的是在 initializer list
中初始化您的指针
Foo::Foo()
: f2(new Foo2(a, b, c))
{}
或者使用 std::make_shared 在你的构造函数中创建它(这个方法隐藏了 new 运算符)
Foo::Foo()
{
f2 = std::make_shared<Foo2>(a, b, c);
}
您的构造函数实现不正确。
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))
{
}
这假定 a
、b
和 c
之前已声明(以编译器可见的方式)并已初始化。
如果a
、b
、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
的构造函数块之前是 called/invoked。语句 f2 = std::make_shared<Foo2>(a, b, c)
构造另一个对象并执行移动赋值(假设 f2
已经构造)而不是初始化。
当 a
、b
、c
需要在 initializer_list 之前计算时,在 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)))
{}
我有一个classFoo
,其中包含classFoo2
的shared_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
这不是创建class的共享指针实例的方法吗?
这就是你想要做的:
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)
部分并非绝对必要。我包含它是为了显示默认情况下发生的情况。
如果a
、b
和c
只在构造函数中创建,则必须重新赋值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 and c are variables that are created in Foo() itself
然后使用赋值运算符:
Foo::Foo() {
f2 = std::make_shared<Foo2>(a, b, c);
}
通过执行 f2(...);您将 operator() 方法调用为 f2.operator()(...);
您需要做的是在 initializer list
Foo::Foo()
: f2(new Foo2(a, b, c))
{}
或者使用 std::make_shared 在你的构造函数中创建它(这个方法隐藏了 new 运算符)
Foo::Foo()
{
f2 = std::make_shared<Foo2>(a, b, c);
}
您的构造函数实现不正确。
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))
{
}
这假定 a
、b
和 c
之前已声明(以编译器可见的方式)并已初始化。
如果a
、b
、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
的构造函数块之前是 called/invoked。语句 f2 = std::make_shared<Foo2>(a, b, c)
构造另一个对象并执行移动赋值(假设 f2
已经构造)而不是初始化。
当 a
、b
、c
需要在 initializer_list 之前计算时,在 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))) {}