标签: smart-pointers

使用make_shared时会发生什么

我感兴趣的是这两行代码是否相同:

shared_ptr<int> sp(new int(1)); // double allocation?
shared_ptr<int> sp(make_shared<int>(1)); // just one allocation?
Run Code Online (Sandbox Code Playgroud)

如果这是真的,有人可以解释为什么在第二行只有一个分配?

c++ smart-pointers make-shared c++11

26
推荐指数
2
解决办法
4414
查看次数

我应该使用shared_ptr还是unique_ptr?

我有一个关于std::unique_ptr和的问题std::shared_ptr.我知道有很多关于何时使用哪一个的问题,但我仍然不确定我是否正确理解它.我在某处读到了智能指针的默认选择std::unique_ptr,但据我了解,我应该更喜欢使用std::shared_ptr.例如,我有:

class B;
class A
{
private:
   B* b;
public:
   B* getB();
};

A::getB()
{
   return b;
}
Run Code Online (Sandbox Code Playgroud)

所以基本上类A拥有指向类型对象的指针,B并且有一个返回该指针的方法.如果我创建了getter,我假设其他一些类可以访问这个指针,因此它应该shared_ptr代替unique_ptr.我是对的,还是我还没有得到它?

c++ smart-pointers shared-ptr unique-ptr c++11

25
推荐指数
2
解决办法
2万
查看次数

如何在C++中启用Rust Ownership范例

系统编程语言Rust使用所有权范例来确保在编译时,在必须释放资源时运行时的成本为零(请参阅"Rust Book on Ownership").

在C++中,我们通常使用智能指针来实现隐藏管理资源分配的复杂性的相同目标.但是有一些不同之处:

  • 在Rust中,始终只有一个所有者,而C++ shared_ptr很容易泄漏所有权.
  • 在Rust中我们可以借用我们不拥有的引用,而C++ unique_ptr不能通过weak_ptr和lock()以安全的方式共享.
  • shared_ptr的引用计数代价很高.

我的问题是:我们如何在以下约束条件下模拟C++中的所有权范例:

  • 任何时候只有一个所有者
  • 可以借用指针并暂时使用它而不用担心资源超出范围(observer_ptr对此无用)
  • 尽可能多的编译时检查.

编辑: 鉴于目前为止的评论,我们可以得出结论:

  • 在编译器中没有编译时支持(我希望有一些我不知道的decltype /模板魔法).可能在其他地方使用静态分析(污点?)
  • 没有引用计数就无法得到这个.
  • 没有标准实现来区分shared_ptrs与拥有或借用语义
  • 可以通过在shared_ptr和weak_ptr周围创建包装类型来自己滚动:

    • owned_ptr:不可复制,移动语义,封装shared_ptr,访问borrowed_ptr
    • borrowed_ptr:copyable,封装weak_ptr,lock方法
    • locked_ptr:不可复制的移动语义,从锁定weak_ptr封装shared_ptr

c++ boost smart-pointers rust

25
推荐指数
1
解决办法
4569
查看次数

为什么std :: make_unique而不是std :: unique_ptr :: make?

为什么C++采用免费函数:

std::make_unique(...);
std::make_shared(...);
Run Code Online (Sandbox Code Playgroud)

而不是使用静态成员函数:

std::unique_ptr::make(...); // static
std::shared_ptr::make(...); // static
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers c++14

25
推荐指数
2
解决办法
2520
查看次数

为什么不应该使用对智能指针的引用?

我记得在某处读到使用对智能指针的引用会导致内存损坏.这只是因为智能指针被销毁后使用了它的引用?或者引用计数搞砸了?

谢谢你的澄清

c++ smart-pointers

24
推荐指数
2
解决办法
1万
查看次数

将constness传播到成员变量指向的数据

对于C++新手来说,允许const成员函数在类引用的对象(通过指针或引用)上调用非const方法通常会让人感到困惑.例如,以下内容完全正确:

class SomeClass
{
    class SomeClassImpl;
    SomeClassImpl * impl_; // PImpl idiom

  public:    

    void const_method() const;
};

struct SomeClass::SomeClassImpl
{
    void non_const_method() { /*modify data*/ }
};

void SomeClass::const_method() const
{
    impl_->non_const_method(); //ok because impl_ is const, not *impl_
};
Run Code Online (Sandbox Code Playgroud)

但是,如果constness传播到尖头对象,它有时会非常方便(我自愿使用PImpl习语,因为它是我认为"constness传播"非常有用的情况之一).

使用指针时,可以通过使用某种智能指针轻松实现这一点,操作符在constness上重载:

template < typename T >
class const_propagating_ptr
{
  public:

    const_propagating_ptr( T * ptr ) : ptr_( ptr ) {}

    T       & operator*()       { return *ptr_; }
    T const & operator*() const { return *ptr_; }

    T       * operator->() …
Run Code Online (Sandbox Code Playgroud)

c++ pointers const smart-pointers

24
推荐指数
1
解决办法
2530
查看次数

成员函数通过模板中的成员函数指针调用shared_ptr

这是一个模板函数,它接受一个指针(或类似指针的对象)和一个成员函数:

template <typename Ptr, typename MemberFunctor>
int example(Ptr ptr, MemberFunctor func )
{
    return (ptr->*func)();
}
Run Code Online (Sandbox Code Playgroud)

如果与普通指针一起使用时有效:

struct C
{
    int getId() const { return 1; }
};

C* c = new C;
example(c, &C::getId);    // Works fine
Run Code Online (Sandbox Code Playgroud)

但它不适用于智能指针:

std::shared_ptr<C> c2(new C);
example(c2, &C::getId);
Run Code Online (Sandbox Code Playgroud)

错误信息:

error: C2296: '->*' : illegal, left operand has type 'std::shared_ptr<C>'
Run Code Online (Sandbox Code Playgroud)

为什么?以及如何制作适合两者的东西?

c++ templates pointers smart-pointers c++11

24
推荐指数
3
解决办法
3931
查看次数

在C++中clone()的最佳签名是什么?

正如Scott Myers写的那样,你可以利用C++的类型系统中的松弛来声明clone()返回一个指向所声明的实际类型的指针:

class Base
{
    virtual Base* clone() const = 0;
};

class Derived : public Base
{
    virtual Derived* clone() const
};
Run Code Online (Sandbox Code Playgroud)

编译器检测到clone()返回指向对象类型的指针,并允许Derived覆盖它以返回指向派生的指针.

希望让clone()返回一个智能指针,它意味着所有权语义的转移,如下所示:

class Base
{
   virtual std::auto_ptr<Base> clone() const = 0;
};

class Derived : public Base
{
    virtual std::auto_ptr<Derived> clone() const;
};
Run Code Online (Sandbox Code Playgroud)

不幸的是,约定的放宽并不适用于模板化的智能指针,编译器也不允许覆盖.

所以,似乎我有两个选择:

  1. 让clone()返回一个"哑"指针,并记录客户端负责处理它.
  2. 让clone()返回一个智能基指针,并让客户端使用dynamic_cast将它们保存到Derived指针(如果需要).

这些方法之一是首选吗?或者有没有办法让我吃掉我的所有权语义转移并且我的强大类型安全呢?

c++ clone smart-pointers covariant-return-types

23
推荐指数
4
解决办法
1万
查看次数

是否可以将C++智能指针与C的malloc一起使用?

我的一些代码仍然使用malloc而不是new.原因是因为我害怕使用,new因为它抛出异常,而不是返回NULL,我可以很容易地检查.结束语每次调用newtry{}catch(){}也看起来并不好.而在使用时malloc我可以做到if (!new_mem) { /* handle error */ }.

所以我有一个问题.我可以同时使用智能指针malloc吗?

就像是:

SmartPointer<Type> smarty = malloc(sizeof(Type));
Run Code Online (Sandbox Code Playgroud)

像这样的东西.

这可能吗?

谢谢,Boda Cydo.

c++ malloc smart-pointers new-operator

23
推荐指数
2
解决办法
1万
查看次数

工厂:如何将临时智能指针传递给函数.C++

我有一堂课Foo

class Foo;
Run Code Online (Sandbox Code Playgroud)

工厂返回指针:

std::unique_ptr<Foo> createFoo(); 
Run Code Online (Sandbox Code Playgroud)

因为Herb告诉我,在Foo的一生中没有特别要求的普通函数应该采用简单的指针:

void plainf(Foo* f);
Run Code Online (Sandbox Code Playgroud)

我的客户应该如何正确地做到这一点?

plainF(createFoo());
Run Code Online (Sandbox Code Playgroud)

如果他不得不写,他会不高兴:

auto someName = createFoo();
plainF(someName.get()); 
Run Code Online (Sandbox Code Playgroud)

c++ factory smart-pointers temporary

23
推荐指数
2
解决办法
2011
查看次数