Lidström先生的主张是,构造shared_ptr<Base> p(new Derived);不要求Base有虚拟析构函数:
Armen Tsirunyan:"真的吗?shared_ptr会正确清理吗?在这种情况下你能否证明可以实现这种效果?"
DanielLidström:" shared_ptr使用自己的析构函数来删除Concrete实例.这在C++社区中被称为RAII.我的建议是你学习RAII的全部内容.它将使你的C++编码在使用时更加容易RAII在所有情况下."
Armen Tsirunyan:"我知道RAII,我也知道,当pn达到0时,最终shared_ptr析构函数可能会删除存储的px.但是如果px有静态类型指针
Base和动态类型指针Derived,那么除非Base有一个虚拟析构函数,会导致不确定的行为.如果我错了,请纠正我."DanielLidström:" shared_ptr知道静态类型是Concrete.它知道这个,因为我在它的构造函数中传递它!看起来有点像魔术,但我可以向你保证它是设计上的并且非常好."
所以,判断我们.如何实现shared_ptr而不需要多态类具有虚拟析构函数是否可能(如果是)?提前致谢
嗨,我今天问了一个问题,关于如何在同一个向量数组中插入不同类型的对象,我的代码就是那个问题
gate* G[1000];
G[0] = new ANDgate() ;
G[1] = new ORgate;
//gate is a class inherited by ANDgate and ORgate classes
class gate
{
.....
......
virtual void Run()
{ //A virtual function
}
};
class ANDgate :public gate
{.....
.......
void Run()
{
//AND version of Run
}
};
class ORgate :public gate
{.....
.......
void Run()
{
//OR version of Run
}
};
//Running the simulator using overloading concept
for(...;...;..)
{
G[i]->Run() ; //will run …Run Code Online (Sandbox Code Playgroud) 将shared_ptr派生类型传递给采用shared_ptr基类型的函数的最佳方法是什么?
我通常通过shared_ptr引用传递s以避免不必要的副本:
int foo(const shared_ptr<bar>& ptr);
Run Code Online (Sandbox Code Playgroud)
但如果我尝试做类似的事情,这不起作用
int foo(const shared_ptr<Base>& ptr);
...
shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
Run Code Online (Sandbox Code Playgroud)
我可以用
foo(dynamic_pointer_cast<Base, Derived>(bar));
Run Code Online (Sandbox Code Playgroud)
但这似乎是次优的,原因有两个:
dynamic_cast对于简单的派生到基础演员来说,A 似乎有点过分.dynamic_pointer_cast创建一个指向传递给函数的副本(虽然是临时的).有更好的解决方案吗?
原来这是一个缺少头文件的问题.此外,我在这里尝试做的是一个反模式.通常,
不影响对象生命周期的函数(即对象在函数持续时间内保持有效)应采用普通引用或指针,例如int foo(bar& b).
使用对象的函数(即,是给定对象的最终用户)应该采用unique_ptrby值,例如int foo(unique_ptr<bar> b).std::move调用者应该将值放入函数中.
延长对象生命周期的函数应采用shared_ptrby值,例如int foo(shared_ptr<bar> b).避免循环引用的通常建议适用.
有关详细信息,请参阅Herb Sutter的回归基础讲座.
我最近在CppCon 2016上观看了Herb Sutter关于"Leak Free C++ ..."的精彩演讲,他谈到了使用智能指针实现RAII(资源获取是初始化) - 概念以及它们如何解决大多数内存泄漏问题.
现在我在想.如果我严格遵循RAII规则,这似乎是一件好事,为什么这与C++中的垃圾收集器有什么不同呢?我知道使用RAII,程序员可以完全控制何时再次释放资源,但是在任何情况下都只对垃圾收集器有益吗?它的效率真的会降低吗?我甚至听说有一个垃圾收集器可以更高效,因为它可以一次释放更大的内存块,而不是在代码中释放小内存块.
class B;
class A
{
public:
A ()
: m_b(new B())
{
}
shared_ptr<B> GimmeB ()
{
return m_b;
}
private:
shared_ptr<B> m_b;
};
Run Code Online (Sandbox Code Playgroud)
假设B是一个在语义上不应该存在于A的生命周期之外的类,也就是说,B对于它自身存在完全没有意义.应该GimmeB退还shared_ptr<B>还是B*?
一般来说,完全避免在C++代码中使用原始指针代替智能指针是一种好习惯吗?
我认为shared_ptr只应该在有明确的转让或共享所有权的情况下使用,我认为在函数分配一些内存,用一些数据填充并返回它的情况下很少见,并且有理解在调用者和被调用者之间,前者现在对该数据"负责".
我有这样的代码:
class RetInterface {...}
class Ret1: public RetInterface {...}
class AInterface
{
public:
virtual boost::shared_ptr<RetInterface> get_r() const = 0;
...
};
class A1: public AInterface
{
public:
boost::shared_ptr<Ret1> get_r() const {...}
...
};
Run Code Online (Sandbox Code Playgroud)
此代码无法编译.
在视觉工作室,它提出
C2555:覆盖虚函数返回类型不同且不协变
如果我不使用boost::shared_ptr但返回原始指针,代码编译(我理解这是由于C++中的协变返回类型).我可以看到这个问题是因为boost::shared_ptr的Ret1不是源自boost::shared_ptr的RetInterface.但我想返回boost::shared_ptr的Ret1在其他类使用,否则我必须在返回后投返回值.
鉴于自有对象的生命周期与其所有者链接的常见情况,我可以使用两种方式之一的唯一指针..
它可以分配:
class owner
{
std::unique_ptr<someObject> owned;
public:
owner()
{
owned=std::unique_ptr<someObject>(new someObject());
}
};
Run Code Online (Sandbox Code Playgroud)
可以使用重置方法:
class owner
{
std::unique_ptr<someObject> owned;
public:
owner()
{
owned.reset(new someObject());
}
};
Run Code Online (Sandbox Code Playgroud)
为了最佳实践,我应该更喜欢一种形式吗?
编辑:对不起伙计们.我简化了这个.堆分配发生在初始化方法中,而不是在ctor中.因此,我无法使用初始化列表.
该std::unique_ptr模板有两个参数:指针对象的类型和删除器的类型.第二个参数有一个默认值,所以你通常只写一些像std::unique_ptr<int>.
该std::shared_ptr模板有虽然只有一个参数:指针对象的类型.但是你也可以使用自定义删除器,即使删除类型不在类模板中.通常的实现使用类型擦除技术来执行此操作.
有没有理由不使用相同的想法std::unique_ptr?
随着它的出现std::unique_ptr,瑕疵std::auto_ptr最终可以得到休息.所以在过去的几天里,我一直在改变我的代码以使用智能指针并delete从我的代码中消除所有代码.
虽然valgrind说我的代码是内存清晰的,但智能指针的语义丰富性将使代码更清晰,更易于理解.
在大多数代码中,转换很简单:std::unique_ptr用于代替拥有对象持有的原始指针,抛弃delete,仔细撒取get(),reset()并move()根据需要调用,以便与其余代码良好地连接.
我现在正在将非拥有原始指针转换为智能指针.
由于我小心对象的生命周期(我确保我的模块只依赖于一个方向),valgrind告诉我,我没有任何未初始化的读取,悬空指针或泄漏.所以,从技术上讲,我现在可以单独留下那些非拥有的原始指针.
但是,一种选择是将那些非拥有的原始指针更改为,std::shared_ptr因为我知道它们是非循环的.或者,将它们留作原始指针会更好吗?
我需要智能指针的资深用户提供一些建议,告诉你使用什么经验法则来决定是否保留非拥有的原始指针,或将它们翻译成std::shared_ptr,请记住我经常进行单元测试和valgrind我的码.
编辑:我可能误解了它的使用std::shared_ptr- 它们是否可以结合使用std::unique_ptr,或者如果我使用的话std::shared_ptr,所有句柄也应该是这样的情况std::shared_ptr?
c++ ×10
smart-pointers ×10
c++11 ×3
shared-ptr ×2
unique-ptr ×2
auto-ptr ×1
boost ×1
casting ×1
covariance ×1
destructor ×1
memory ×1
memory-leaks ×1
standards ×1
type-erasure ×1
vector ×1