[英]Dependency injection w/ smart pointers in C++
我正在嘗試在C ++項目中實現依賴項注入模式,手動執行注入(無框架)。 因此,我正在使用工廠函數手動創建依賴項,並將其傳遞給使用它們的類。 我的問題是,當依賴關系圖的根(本身是由智能指針管理的類實例)超出范圍時,其依賴關系(在類中引用的智能指針)不會被破壞(valgrind顯示丟失的內存塊) 。
我看到的只是這樣的基本示例,其中A類依賴於B類:
class B{
public:
B() {}
~B() {}
};
class A{
std::unique_ptr<B> b_;
public:
A(std::unique_ptr<B> b) : b_(std::move(b)) { }
~A(){}
};
namespace A_Factory {
std::unique_ptr<A> getInstance(){
return std::make_unique<A>(std::make_unique<B>());
}
}
int main(void){
auto a = A_Factory::getInstance();
//do some A stuff
} //a goes out of scope and gets deleted?
因此,在此示例中,我使用A_Factory::getInstance
獲取A,因此使用A的任何內容都不知道A是如何創建的,也不知道A如何創建其依賴項。 據我了解,使用智能指針,它們將在超出范圍時自動刪除, 希望一旦根超出范圍, 它們便會鏈接依賴圖 。 如果必須實現代碼以消除依賴關系,那么智能指針並不會帶來太多好處。
因此,我無法確定我是否沒有使用智能指針正確地進行設置,或者valgrind並未告訴我我的意思。 我對valgrind的理解是,它實際上僅指出了代碼范圍內的問題,因此,如果標准庫正在刪除依賴項,則valgrind可能無法反映這一點。 但是,當我使用包裹在瑣碎類(沒有依賴項)上的智能指針對一個簡單程序運行valgrind時,它不會顯示任何丟失的內存。
我還將注意到,在這里我在stackoverflow上看到的一些示例對我沒有用,例如不在A的初始化列表中調用std::move
。 而且我想避免傳遞任何原始指針。
我正在使用不包含make_unique的g ++ 4.8.5,但是我添加了Herb Sutter的建議的make_unique實現,並在顯示未泄漏的valgrind下運行測試。
#include <iostream>
#include <cstdlib>
#include <memory>
using namespace std;
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T ( std::forward<Args>(args)...));
}
class B{
public:
B() {}
~B() {}
};
class A{
std::unique_ptr<B> b_;
public:
A(std::unique_ptr<B> b) : b_(std::move(b)) { }
~A(){}
};
namespace A_Factory {
std::unique_ptr<A> getInstance(){
return make_unique<A>(make_unique<B>());
}
}
int main(void){
auto a = A_Factory::getInstance();
}
也許您的問題源於正在使用的編譯器中的make_unique實現?
我已經在所有構造函數和析構函數中使用print語句對代碼進行了檢測。 此外,我禁用了所有編譯器生成的構造函數,以確保它們不運行:
#include <iostream>
#include <memory>
class B{
public:
B() {std::cout << "B()\n";}
~B() {std::cout << "~B()\n";}
B(const B&) = delete;
};
class A{
std::unique_ptr<B> b_;
public:
A(std::unique_ptr<B> b) : b_(std::move(b)) {std::cout << "A()\n";}
~A(){std::cout << "~A()\n";}
A(const A&) = delete;
};
namespace A_Factory {
std::unique_ptr<A> getInstance(){
return std::make_unique<A>(std::make_unique<B>());
}
}
int main(void){
auto a = A_Factory::getInstance();
//do some A stuff
}
該程序為我輸出:
B()
A()
~A()
~B()
我正在為每個析構函數計數一個構造函數。 您在編譯器中看到相同的東西嗎? 如果是這樣,一切都很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.