我有一个类Foo
,其中包含类Foo2
的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
这不是创建类的共享指针实例的方法吗?
如果仅在构造函数中创建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 和 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))
{
}
这假定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
。 语句f2 = std::make_shared<Foo2>(a, b, c)
构造另一个对象并执行移动赋值(假定f2
已经构造(而不是初始化。
在a
、b
、c
之前需要计算时,在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))) {}