我感兴趣的是这两行代码是否相同:
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)
如果这是真的,有人可以解释为什么在第二行只有一个分配?
我有一个关于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.我是对的,还是我还没有得到它?
系统编程语言Rust使用所有权范例来确保在编译时,在必须释放资源时运行时的成本为零(请参阅"Rust Book on Ownership").
在C++中,我们通常使用智能指针来实现隐藏管理资源分配的复杂性的相同目标.但是有一些不同之处:
我的问题是:我们如何在以下约束条件下模拟C++中的所有权范例:
编辑: 鉴于目前为止的评论,我们可以得出结论:
可以通过在shared_ptr和weak_ptr周围创建包装类型来自己滚动:
为什么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++新手来说,允许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) 这是一个模板函数,它接受一个指针(或类似指针的对象)和一个成员函数:
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)
为什么?以及如何制作适合两者的东西?
正如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)
不幸的是,约定的放宽并不适用于模板化的智能指针,编译器也不允许覆盖.
所以,似乎我有两个选择:
这些方法之一是首选吗?或者有没有办法让我吃掉我的所有权语义转移并且我的强大类型安全呢?
我的一些代码仍然使用malloc而不是new.原因是因为我害怕使用,new因为它抛出异常,而不是返回NULL,我可以很容易地检查.结束语每次调用new的try{}catch(){}也看起来并不好.而在使用时malloc我可以做到if (!new_mem) { /* handle error */ }.
所以我有一个问题.我可以同时使用智能指针malloc吗?
就像是:
SmartPointer<Type> smarty = malloc(sizeof(Type));
Run Code Online (Sandbox Code Playgroud)
像这样的东西.
这可能吗?
谢谢,Boda Cydo.
我有一堂课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++ ×10
smart-pointers ×10
c++11 ×3
pointers ×2
boost ×1
c++14 ×1
clone ×1
const ×1
factory ×1
make-shared ×1
malloc ×1
new-operator ×1
rust ×1
shared-ptr ×1
templates ×1
temporary ×1
unique-ptr ×1