C++ 关于boost::shared_ptr的困惑

C++ 关于boost::shared_ptr的困惑,c++,pointers,reference,shared-ptr,C++,Pointers,Reference,Shared Ptr,我的问题围绕着是否必须从接口公开boost::shared_ptr的使用,以及是否应该从接口公开原始指针或引用 以一个有雇员的人为例。Employeer以向量。 如果我以后想将实现更改为使用johns_very_own_shared_ptr而不是boost变体,那么我是否陷入了旧的实现中 差不多,但这不是不可能解决的。(我怀疑在C++0x中,自由地使用auto关键字会使这更容易处理,因为即使调用代码没有使用typedefs,也不需要对调用代码进行太多修改。)但是,为什么要这样做呢 另一方面,如果

我的问题围绕着是否必须从接口公开boost::shared_ptr的使用,以及是否应该从接口公开原始指针或引用

以一个有雇员的人为例。Employeer以
向量
对其所有员工进行内部维护。因此,最佳实践是否规定任何涉及人员的接口都应该是共享的\u ptr包装的人员

例如,是否全部或仅部分确定:

Person Employeer::getPresidentCopy();
Person& Employeer::getPresidentRef();
Person* Employeer::getPresidentRawPtr();
shared_ptr<Person> Employeer::getPresidentSharedPtr();
Person Employeer::getPresidentCopy();
人员和雇员::getPresidentRef();
Person*Employeer::getPresidentRawPtr();
共享的员工::getPresidentSharedPtr();
或例如:

void Employeer::hireByCopy(Person p);
void Employeer::hireByRef(Person& p);
void Employeer::hireByRawPtr(Person* p);
void Employeer::hireBySharedPtr(shared_ptr<Person> p);
void Employeer::hireByCopy(个人p);
无效雇员:雇佣者(个人和个人);
无效雇主:雇佣者(个人*p);
无效员工::员工共享ptr(共享);
如果我以后想将实现更改为使用johns_very_own_shared_ptr而不是boost变体,那么我是否陷入了旧的实现中

另一方面,如果我从接口公开原始指针或引用,是否会有人从共享\u ptr下删除内存的风险?还是我要冒着被删除共享ptr并使我的引用无效的风险



请参见my,以获取与此相关的示例。

您不必分发共享的\u ptr,但如果分发原始指针,则在对象被销毁后,会有一些原始指针持续存在的风险

有致命的后果

所以,分发引用通常是可以的(如果客户机代码采用address,那么这并不比客户机代码采用*shared_ptr的地址更重要),但是原始指针,请首先考虑


干杯,

当您使用
shared\u ptr
s时,我不应该给用户原始指针。用户可以删除它,这将导致双重删除

要隐藏
boost:shared_ptr
的用法,可以使用
typedef
隐藏实际类型,并改用此新类型

typedef boost::shared_ptr<Person> Person_sptr;
typedef boost::shared_ptr Person_sptr;

我会引入一个
typedef
,使自己免受变化的影响。大概是这样的:

typedef std::shared_ptr<Person> PersonPtr;

PersonPtr Employeer::getPresident() const;
typedef std::shared_ptr PersonPtr;
员工:getPresident()const;

我将像这样的typedef与转发声明一起放在(仅一个)标题中。如果我愿意的话,可以很容易地进行更改。

在这里分发
共享\u ptr
的唯一原因是如果返回对象引用的生存期没有直接绑定到它在向量中驻留的生存期


如果您希望某人在不再是
员工后能够访问
人员
,则
共享的ptr
将是合适的。假设您正在为不同的
雇主将
人员
移动到
向量

我在一个中等规模的项目上工作,该项目链接到多个库中。有些库有自己的内存管理子系统(APR、MFC),这让我很恼火。无论他们对世界的看法是好是坏,它都与其他人完全不同,需要比其他人多一点的代码

此外,这些库使得使用或更难()替换
malloc
new

我在自己的代码中经常使用共享指针,但我不想告诉其他人如何管理他们的内存。相反,尽可能分发对象(让库用户决定何时以及如何分配内存),如果不可能,则执行以下操作之一:

  • 分发原始指针(加上指针可以是
    delete
    d的承诺,或者调用函数来释放对象)
  • 接受一个函数或类似STL分配器的参数,这样您就可以钩住用户用于内存管理的任何内容(可以随意默认为
    new
    std::allocator
  • 让您的库用户为您分配内存缓冲区()
  • 使用这种库并不一定是令人讨厌的:

    // situation (1) from above
    std::shared_ptr<Foo> foo(Library_factory::get_Foo(), Library_factory::deallocate);
    
    // situation (2) above (declaration on next line is in a header file)
    template<typename allocator=std::allocator<Foo> > Foo* library_function_call();
    boost::shared_ptr<Foo> foo = library_function_call();
    
    // situation (3) above, need to fill a buffer of ten objects
    std::vector<Foo> foo_buffer(10);
    fill_buffer(&foo_buffer[0], foo_buffer.size());
    
    //上面的情况(1)
    std::shared\u ptr foo(库工厂::get\u foo(),库工厂::解除分配);
    //上述情况(2)(下一行的声明位于头文件中)
    模板Foo*库函数调用();
    boost::shared_ptr foo=库函数调用();
    //上述情况(3),需要填充10个对象的缓冲区
    std::向量foo_缓冲区(10);
    fill_buffer(&foo_buffer[0],foo_buffer.size());
    
    例如,是否全部或仅部分确定:

    Person Employeer::getPresidentCopy();
    Person& Employeer::getPresidentRef();
    Person* Employeer::getPresidentRawPtr();
    shared_ptr<Person> Employeer::getPresidentSharedPtr();
    
    这取决于你想完成什么。为什么向量保存
    shared_ptr
    s而不是直接按值存储
    Person
    s?(您是否考虑过
    boost::ptr_vector
    ?)

    你也应该考虑一下,你真正应该提出的是<代码>弱者PTR < /代码>。 如果我以后想将实现更改为使用johns_very_own_shared_ptr而不是boost变体,那么我是否陷入了旧的实现中

    差不多,但这不是不可能解决的。(我怀疑在C++0x中,自由地使用
    auto
    关键字会使这更容易处理,因为即使调用代码没有使用
    typedef
    s,也不需要对调用代码进行太多修改。)但是,为什么要这样做呢

    另一方面,如果我从接口公开原始指针或引用,是否会有人从共享\u ptr下删除内存的风险

    是的,但那不是你的问题。人们可以从
    共享的\u ptr
    中提取原始指针,也可以
    删除它。但是如果你想避免不必要的不安全,不要在这里返回原始指针。引用要好得多,因为从来没有人认为它们应该从api中删除和引用。(无论如何,我希望如此。);;;;