[英]c++ shared_ptr does not provide a call operator
我有一個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);
}
這是你想要做的:
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)
部分不是絕對必要的。 我包含它以顯示默認情況下發生的情況。
通過做 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(){ //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))) {}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.