我最近尝试了解如何使用std::shared_ptr
。在修改现有代码时,我发现自己在使用成员变量分配时(在初始化列表之外)感到困惑。
我的旧代码:
Class A {
Base* member_var;
A() {
this->member_var = new Derived();
}
};
我的新代码:
Class A {
std::shared_ptr<Base> member_var;
A() {
//Note the shared_ptr is given type Derived, matching the object.
this->member_var = std::shared_ptr<Derived> (new Derived());
}
};
这是对的吗?或者这可能更正确?:
Class A {
std::shared_ptr<Base> member_var;
A() {
//Note the shared_ptr is of type Base, matching the member type.
this->member_var = std::shared_ptr<Base> (new Derived());
}
};
这两个陈述之间有什么区别。
令人担忧的是,我似乎无法找到我在这里尝试做的任何代码示例。我使用std::shared_ptr
的方法是错误的吗?
编辑:感谢大家的帮助。我想我引起了一些困惑。为了将来的可读性,我将扩展为什么我选择采用这种方法。我选择用一个简单的代码示例来说明我的问题。在我的实际问题中,我不使用Class A
,实际上我使用的是结构。这个结构的唯一目的是帮助我整齐地抓住各种不同对象的许多实例。我经常最终单独传递(通过引用)每个对象,而不是结构本身,作为函数的参数。此外,当我将整个结构作为参数时,我倾向于通过值传递这个结构。因此我有兴趣制作这些shared_ptr,而不是unique_ptr。我一直在讨论改变所有内容并将所有这些封装在一个类中,比如我的示例中的Class A
,并将类的实例传递给对象实例。在这种情况下,我同意所有评论过的人,unique_ptr
似乎更合适。
当然,结构和类之间没有根本区别。我只是倾向于按值传递结构的实例(如果它们包含的都是指针),并且通过引用传递类的实例。也许这是我个人的怪癖?
首先,关于多态的使用,这里有两个可能的派生类,其中一个是在运行时选择的。我希望处理基类,它可以用于所有意图和目的,是一个抽象类。
我仍然感到惊讶,这不是一个更常见的情况。也许上面的段落突出了进一步的不良做法。在这种情况下,我将很高兴听到它。
答案 0 :(得分:5)
我这样写:
A() : member_var(std::make_shared<Derived>()) { }
在Modern C ++中,您应该尽可能避免使用new
。如果您无法在初始化列表中初始化member_var
,请执行以下操作:
A()
{
// ...
member_var = std::make_shared<Derived>();
}
As mentioned by KerrekSB in the comments,我还建议您考虑是否确实需要共享所有权,或者unique_ptr
是否足够。
如果是这种情况,则应使用unique_ptr
代替:通常,表达最低要求是一件好事 - 这会同时为您提供性能和更好的自我记录代码。
不幸的是,在C ++ 11中,您必须求助于new
来创建指向新创建对象的unique_ptr
:
A() : member_var(new Derived()) { }
或者,如果您不能使用初始化列表:
member_var.reset(new Derived());
另一方面,在提供std::make_unique<>
的C ++ 14中,我宁愿写:
A() : member_var(std::make_unique<Derived>()) { }
或者,如果您不能使用初始化列表:
member_var = std::make_unique<Derived>();