为了解决我的应用程序中一个非常特殊的问题,我需要一个指向已分配数据的共享指针,但对于外部世界,底层数据类型应保持隐藏状态.
我可以通过创建我的其他所有类继承的某种Root类来解决这个问题,并在此Root类上使用shared_ptr,如下所示:
std::shared_ptr<Root>
Run Code Online (Sandbox Code Playgroud)
然而:
奇怪的是,似乎你可以在void上创建一个shared_ptr,这似乎工作正常,如下例所示:
class X
{
public:
X() {std::cout << "X::ctor" << std::endl;}
virtual ~X() {std::cout << "X::dtor" << std::endl;}
};
typedef std::shared_ptr<void> SharedVoidPointer;
int main()
{
X *x = new X();
SharedVoidPointer sp1(x);
}
Run Code Online (Sandbox Code Playgroud)
x被正确删除,在一个更大的实验中,我可以验证共享指针确实完成了它需要做的事情(删除x,最后一个shared_ptr结束了灯光).
当然,这解决了我的问题,因为我现在可以使用SharedVoidPointer数据成员返回数据,并确保它正确地清理它应该在哪里.
但这是否可以保证在所有情况下都有效?它显然适用于Visual Studio 2010,但这是否也可以在其他编译器上正常工作?在其他平台上?
#include <memory>
class bar{};
void foo(bar &object){
std::unique_ptr<bar> pointer = &object;
}
Run Code Online (Sandbox Code Playgroud)
我想将对象的地址分配给指针.上面的代码显然不会编译,因为赋值运算符的右侧需要是std :: unique_ptr.我已经尝试过了:
pointer = std::make_unique<bar>(object)
Run Code Online (Sandbox Code Playgroud)
但它在编译过程中会抛出许多错误.我怎样才能做到这一点?
更新
如答案中所述 - 使用该std::unique_ptr::reset方法导致未定义的行为.现在我知道,在这种情况下我应该使用标准指针.
现在shared_ptr是在tr1中,您认为应该如何使用std::auto_ptr?它们都有不同的用例,但所有用例auto_ptr都可以解决shared_ptr.auto_ptr如果您想明确表达只有一个类在任何给定点拥有所有权,您会放弃或继续使用它吗?
我的看法是使用auto_ptr可以增加代码的清晰度,正是通过添加细微差别和代码设计的指示,但另一方面,它在培训新程序员时又增加了另一个微妙的问题:他们需要理解智能指针和他们如何工作的细节.当你在任何地方只使用一个智能指针时,你可以放下一个规则"将所有指针包裹起来shared_ptr"并完成它.
你对此有何看法?
谁能解释上面提到的类型和一些样本用法之间的区别,以清楚地解释两者之间的区别?
任何帮助将非常感谢!注意:这个问题是另一个问题的副产品
我曾经写过这样的代码:
class P {};
class Q: public P {};
class A {
// takes ownership
A(P* p): p_(p) {}
scoped_ptr<P> p_;
};
A a(new Q);
Run Code Online (Sandbox Code Playgroud)
使用C++ 0x,我应该将A类重写为:
class A {
// takes ownership
A(unique_ptr<P>&& p): p_(p) {}
unique_ptr<P> p_;
};
Run Code Online (Sandbox Code Playgroud) 我正在使用enable_shared_from_this<Base>然后继承Base.当尝试使用shared_from_this()in Derived的构造函数(而不是初始化列表)时,我得到一个异常.事实证明,内部弱指针为空并且根本不指向this.怎么会发生这种情况?我的其他用例完全正常.我甚至不知道从哪里开始.我低头看了源代码enable_shared_from_this,它看起来像指针永远是nullptr.
当尝试使用auto_ptr带有forward-declaration声明的类型时,如下所示:
class A;
...
std::auto_ptr<A> a;
Run Code Online (Sandbox Code Playgroud)
A没有调用析构函数(显然,因为auto_ptr内部delete的底层指针和不完整类型的析构函数不能被调用).
但是,相同的代码工作正常,并在使用时调用析构函数std::shared_ptr而不是std::auto_ptr.怎么解释?
拥有通常的Base - > Derived层次结构,如:
class Fruit { ... };
class Pear : Fruit { ... };
class Tomato : Fruit { ... };
std::vector<Fruit*> m_fruits;
Run Code Online (Sandbox Code Playgroud)
是否有意义(例如:它有更好的性能)使用emplace_back而不是push_back?
std::vector::emplace_back( new Pear() );
std::vector::emplace_back( new Tomato() );
Run Code Online (Sandbox Code Playgroud) 我试图找到一些简单的方法来安置元素,std::vector<std::shared_ptr<int>>但不能带来任何东西.std::shared_ptr将指针作为参数,所以我仍然可以这样写:
std::vector<std::shared_ptr<int>> vec;
vec.emplace_back(new int(10));
Run Code Online (Sandbox Code Playgroud)
但是,new如果可能的话,我不想手工使用,如果可能的话,我宁愿使用std::make_shared.问题是,如果我真的想要使用它,我必须使用它push_back而失去就地构造的优势:
std::vector<std::shared_ptr<int>> vec;
vec.push_back(std::make_shared<int>(10));
Run Code Online (Sandbox Code Playgroud)
有没有什么办法让两者的优点emplace_back和std::make_shared?如果没有,在这种情况下是否应该遵循指引?
编辑:实际上,我问了这个问题,但有一个无关的问题.Andy的答案是好的,并且使用这两个emplace函数并没有任何实际问题std::make_shared.
c++ ×10
smart-pointers ×10
c++11 ×6
shared-ptr ×4
auto-ptr ×2
boost ×1
c++14 ×1
coding-style ×1
com ×1
pointers ×1
std ×1
tr1 ×1
unique-ptr ×1
visual-c++ ×1