我最近尝试学习如何使用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似乎更合适。

当然,结构和类之间没有根本区别。我只是倾向于按值传递结构实例(如果它们包含的全部是指针),而按实例传递类的实例。也许那是我的个人怪癖?

首先,关于多态的使用,这里有两个可能的派生类,其中一个是在运行时选择的。我希望处理基类,该类出于所有意图和目的,是一个抽象类。

我仍然感到惊讶的是,这种情况并不常见。也许以上段落强调了进一步的不良做法。在这种情况下,我将不胜感激。

最佳答案

我会这样写:

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>();

关于c++ - shared_ptr成员变量的多态分配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17493146/

10-13 07:10