2017-06-13 79 views
7

我有一個代碼庫,這使得大量使用的語法如下工作:我應該使用shared_ptr <Object> myObject =(shared_ptr <Object>)new Object()來訪問私有構造函數嗎?

shared_ptr<Object> myObject = (shared_ptr<Object>) new Object(); 

我發現我不能make_shared訪問私有構造函數,但shared_ptr<Object> myObject = (shared_ptr<Object>) new Object();工作得很好。我應該使用它,只是因爲它似乎工作?有什麼危險嗎?它與make_shared有什麼不同?

我知道答案的問題this,使make_shared之間的比較:

std::shared_ptr<Object> p2(new Object("foo")); 

,但我一直沒能找到我碰到的語法的參考。它是不同的,還是它與上述相同?

+3

第一行代碼看起來像一個'C'風格的演員:看到(1)在這裏:http://en.cppreference.com/w/cpp/language/explicit_cast –

+1

看看這裏:https:/ /stackoverflow.com/questions/32168/c-cast-syntax-styles – zdan

回答

10

make_shared將對象分配在與控制塊相同的內存塊中。這可以提高緩存一致性並削減分配。

的一種方式,允許make_shared要做到這一點是讓你的類中的一個私人令牌,而且消耗了令牌公共構造

class Object { 
private: 
    struct token_t{ private: token_t() {}; friend class Object; }; 
    static token_t token() { return {}; } 
    Object() = default; 
public: 
    Object(token_t):Object() {} 
}; 

現在我們可以make_shared<Object>(Object::token())

這給了我們一個分配,並沒有違反建築的隱私,因爲只有訪問私有字段Object的東西才能調用該構造函數。但是,它們可以將令牌傳遞給另一個函數(如make_shared),並且它又可以調用相關的構造函數。當然,這與更多的論據一起工作。

至於你的語法:

std::shared_ptr<Object> myObject = (std::shared_ptr<Object>) new Object(); 

(std::shared_ptr<Object>) new Object();簡單明確地構建從new Object()一個shared_ptr<Object>。它相當於std::shared_ptr<Object>(new Object)

然後我們拿這個prvalue,並從它構造myObject。在C++ 03 11和14中,這種複製/移動結構被省略了。在C++ 17中,prvalue「構造指令」直接應用於myObject。實際上,這會產生相同的機器代碼(除非你是個傻瓜,並明確告訴你的編譯器不要遺漏構造)。

總之,它的工作原理。唯一的缺點是從Object分配中雙重分配單獨的控制塊。

+0

這是一個很好的答案,謝謝:) – nikaza

+0

我得到一個錯誤...它是'token()'函數的方式是私有的...所以它不能在'make_shared <>()'調用中使用。 –

+2

@alexis問題的關鍵在於make共享只能在上下文中使用令牌調用,您可以從該類訪問私有數據(或者通過代理向他們授予權限,並通過代理向您傳遞來自此類上下文的令牌)。如果你根本不需要訪問控制,只需將構造函數公開就可以了。即假設'static std :: shared_ptr Class :: make(){return std :: make_shared (token()); }' – Yakk

相關問題