C++ 通过传递外部指针或内部调用new构造的类,是否可以在销毁时天真地删除此指针?
我有一个类A,它有一个指向类B的指针作为它的一个字段:C++ 通过传递外部指针或内部调用new构造的类,是否可以在销毁时天真地删除此指针?,c++,memory,dynamic,delete-operator,C++,Memory,Dynamic,Delete Operator,我有一个类A,它有一个指向类B的指针作为它的一个字段: class A { private: B *ptr; public: A(B*); A(); ~A(); } A::A(B *ptr) { this->ptr = ptr; } A::A() { this->ptr = new B(); } A::~A() { delete this->ptr; } 我希望析构函数只在由new分配的情况下删除B,我只能通过设置
class A {
private:
B *ptr;
public:
A(B*);
A();
~A();
}
A::A(B *ptr)
{
this->ptr = ptr;
}
A::A()
{
this->ptr = new B();
}
A::~A()
{
delete this->ptr;
}
我希望析构函数只在由new分配的情况下删除B,我只能通过设置一个标记来存储指针的原点(这样,只有在构建a的过程中分配了ptr时才会调用delete),或者是否有更优雅的解决方案,也就是,我可以在任何指针上调用delete(我知道,如果传入的指针是使用new分配的,那么它也将被删除,但是如果指针是从调用A的构造函数的作用域传入的,那么显然删除它是未定义的)
还是有更优雅的解决方案
不,不是真的;它需要清楚地记录谁拥有这个指针。它看起来像你的类,所以你能自己构造ptr
吗
#include <memory>
class A {
private:
std::unique_ptr<B> ptr;
public:
A(some_data args)
: ptr(new B(args)) { };
A();
}
#包括
甲级{
私人:
std::唯一的ptr ptr;
公众:
A(一些_数据参数)
:ptr(新B(args)){};
A();
}
如果您的类不拥有也可以的指针,就不要取消分配它。否则您将需要在外部设置一个标志(即,deallocu on_destruct
)来知道该做什么,这可能会变得混乱
还是有更优雅的解决方案
不,不是真的;它需要清楚地记录谁拥有这个指针。它看起来像你的类,所以你能自己构造ptr
吗
#include <memory>
class A {
private:
std::unique_ptr<B> ptr;
public:
A(some_data args)
: ptr(new B(args)) { };
A();
}
#包括
甲级{
私人:
std::唯一的ptr ptr;
公众:
A(一些_数据参数)
:ptr(新B(args)){};
A();
}
如果您的类不拥有也可以的指针,就不要取消分配它。否则您将需要在外部设置一个标志(即,
dealloc\u on\u destruct
)要知道该做什么,这可能会变得混乱。更优雅的解决方案是不让类拥有不同的所有权模型,在这种情况下,是由类拥有还是不由类拥有。不要将这两种想法混合在同一类类型中,因为这只会混淆用户/客户机(违反了最小惊喜原则)
创建具有所需不同行为的单独类,或者选择一个所有权模型并强制客户机坚持使用它(在非默认构造函数中传入并转移所有权,或者不允许自分配).更优雅的解决方案是不要让类拥有不同的所有权模型,在这种情况下,是由类拥有还是不由类拥有。不要将这两种想法混合在同一类类型中,因为这只会混淆用户/客户机(违反最小意外原则)
创建具有所需不同行为的单独类,或者选择一个所有权模型并强制客户机坚持使用它(在非默认构造函数中传入并转移所有权,或者不允许自分配).仅凭您提供的代码无法回答这个问题。真正的问题是为什么您可以接受或不接受指针,以及如果指针传递给您,谁拥有内存 根据您的对象在特定域中应该做什么,可以采取不同的替代方案。例如,如果您可以与调用者共享所有权,那么您应该采取
共享的\u ptr
,如果您要保留对象的所有权,则应使用唯一的\u ptr
在int中明确说明如果您的对象将要获得所有权,如果所有权不被共享,那么考虑将引用传递给对象(即使您在内部存储指针),在这种情况下,您可以将所有权与实际使用分开:
// option 1: shared ownwership
class A {
std::shared_ptr<B> ptr;
public:
A( std::shared_ptr<B> const & p ) : ptr(p) {}
A() : ptr( std::make_shared<B>() ) {}
};
// option 2: grab ownership
class A {
std::unique_ptr<B> ptr;
public:
A( std::unique_ptr<B> p ) : ptr( std::move(p) ) {}
A() : ptr( new B(); }
};
// option 3: no ownership (unless we create the object)
// (separating concerns: ref to access the object, ptr to manage it)
class A {
std::unique_ptr<B> ptr; // only ownership
B * ref;
public:
A( B & b ) : ptr(), ref(&b) {}
A() : ptr( new B() ), ref(ptr.get()) {}
// Internally use 'ref' to access the object the destructor will delete it
// if needed
};
//选项1:共享所有权
甲级{
std::共享的ptr;
公众:
A(std::shared_ptr const&p):ptr(p){
A():ptr(std::make_shared()){}
};
//选择2:攫取所有权
甲级{
std::唯一的ptr ptr;
公众:
A(std::unique_ptr p):ptr(std::move(p)){
A():ptr(新的B();}
};
//选项3:无所有权(除非我们创建对象)
//(分离关注点:ref访问对象,ptr管理对象)
甲级{
std::unique_ptr ptr;//仅所有权
B*ref;
公众:
A(B&B):ptr(),ref(&B){}
A():ptr(新B()),ref(ptr.get()){}
//在内部使用“ref”访问对象,析构函数将删除该对象
//如果需要
};
仅凭您提供的代码无法回答这个问题。真正的问题是为什么您可以接受或不接受指针,以及如果指针传递给您,谁拥有内存
根据您的对象在特定域中应该做什么,可以采取不同的替代方案。例如,如果您可以与调用者共享所有权,那么您应该采取共享的\u ptr
,如果您要保留对象的所有权,则应使用唯一的\u ptr
在int中明确说明如果您的对象将要获得所有权,如果所有权不被共享,那么考虑将引用传递给对象(即使您在内部存储指针),在这种情况下,您可以将所有权与实际使用分开:
// option 1: shared ownwership
class A {
std::shared_ptr<B> ptr;
public:
A( std::shared_ptr<B> const & p ) : ptr(p) {}
A() : ptr( std::make_shared<B>() ) {}
};
// option 2: grab ownership
class A {
std::unique_ptr<B> ptr;
public:
A( std::unique_ptr<B> p ) : ptr( std::move(p) ) {}
A() : ptr( new B(); }
};
// option 3: no ownership (unless we create the object)
// (separating concerns: ref to access the object, ptr to manage it)
class A {
std::unique_ptr<B> ptr; // only ownership
B * ref;
public:
A( B & b ) : ptr(), ref(&b) {}
A() : ptr( new B() ), ref(ptr.get()) {}
// Internally use 'ref' to access the object the destructor will delete it
// if needed
};
//选项1:共享所有权
甲级{
std::共享的ptr;
公众:
A(std::shared_ptr const&p):ptr(p){
A():ptr(std::make_shared()){}
};
//选择2:攫取所有权
甲级{
std::唯一的ptr ptr;
公众:
A(std::unique_ptr p):ptr(std::move(p)){
A():ptr(新的B();}
};
//选项3:无所有权(除非我们创建对象)
//(分离关注点:ref访问对象,ptr管理对象)
甲级{
std::unique_ptr ptr;//仅所有权
B*ref;
公众:
A(B&B):ptr(),ref(&B){}
A():ptr(新B()),ref(ptr.get()){}
//在内部使用“ref”访问对象,析构函数将删除该对象
//如果需要
};
除了其他人所说的(避免这种设计):如果