2011-08-25 74 views
1

因此,我已经听到过有关现代C++风格的一个经验法则,那就是不应该使用new或delete,而应该使用智能指针。所以当我有一个类,其中一个成员是指向另一个对象的指针时,如何去解决这个问题。通过使用智能指针,我可以避免需要删除,但我仍然需要使用新建对象。例如。是下面的“典型”现代C++风格,还是应该怎么做呢?在“现代C++”中作为类成员对象的指针

 

#include 
#include 

class B { 
public: 
    B() { std::printf("constructing B\n");} 
    ~B() { std::printf("destroying B\n");} 
}; 

class A { 
public: 
    A() 
    { 
     std::printf("constructing A\n"); 
     b = std::unique_ptr(new B()); 
    } 
    ~A() { std::printf("destroying A\n");} 

private: 
    std::unique_ptr b; 
}; 

int main() 
{ 
    A a; 
    return 0; 
} 

 
+2

我知道Boost有这个,我假设C++ 0x有类似的东西,但是你可以使用'boost :: make_shared (9)'而不是'boost :: shared_ptr (new int(9))' – Dawson

+2

不要听那些试图告诉你这个或那个没有更多的“现代风格”的人。建议可能是好的或坏的,但是你需要在你正在编写的特定代码中为你自己(和你的继任者)提供有用的帮助。否则,你只是参加一次货物崇拜。 –

+0

我认为你很难建议设计C++程序与RAII相关,因此不需要或很少需要实现显式析构函数(这也意味着几乎不需要使用delete来显式释放对象)。 – mloskot

回答

7

您使用new。使用new没有任何问题,它应该尽可能少使用。

(在另一方面delete,应该几乎从来没有被使用,因为它的使用应该始终可以在某种RAII的封装处理像智能指针或容器)。


注意当使用智能指针时,您应始终将new的结果分配给指定的智能指针或使用reset。在你的情况,你想使用:

A() : b(new B()) { } 

或:

A() 
{ 
    std::unique_ptr<B> x(new B()); 
    b = std::move(x); 
} 

或:

A() { b.reset(new B()); } 

(为什么这很重要,请参阅 “最佳实践” 一节的boost::shared_ptr documentation。)

+0

+1。只要所有新表达式都立即包含在管理对象的构造函数中(单责任原则),就可以在类构造函数内使用'new'。在独立代码中,你可以使用'make_shared'来避免'new',但如果你使用'unique_ptr',那么一个好的'new'就可以。 –