如果我需要使用多态,是否应该使用裸指针而不是unique_ptr?

21
如果我需要多态性,我应该使用原始指针而不是unique_ptr吗?
我看到了一些线程展示如何使用unique_ptr实现多态行为。 我不确定这是否值得麻烦,我宁愿使用原始指针。 您能否就此发表评论,您对原始指针与智能指针在这种情况下的看法?

2
不要使用非私有的裸指针。它们难以正确使用,实际上是不可能的。 - Kerrek SB
1
这是一个很好的观点。在我的情况下,我可以将它们保持私密。 - user3111311
你能指出这些线程吗?据我所知,就多态而言,原始指针、unique_pointershared_pointer之间没有区别。它们都以相同的方式工作。 - balki
我不确定这是否值得麻烦。不知道你的意思,裸指针比智能指针更麻烦。 - fredoverflow
3个回答

23

以下简单的代码展示了从多态性的角度而言,std::unique_ptr 能够正常工作,并打印出 "Hello from Derived."

#include <iostream>
#include <memory>
using std::cout;

struct Base 
{
    virtual ~Base() { }

    virtual void SayHello()
    {
        cout << "Hello from Base.\n";
    }
};

struct Derived : public Base
{
    void SayHello() override
    {
        cout << "Hello from Derived.\n";
    }
};

int main()
{
    std::unique_ptr<Base> pBase( new Derived() );
    
    // Or using std::make_unique:
    //
    // std::unique_ptr<Base> pBase = std::make_unique<Derived>();      
    
    pBase->SayHello();
}

总之,观察原始指针是可以的;您必须注意的是拥有原始指针。 应该将拥有原始指针安全地包装在RAII边界内(使用unique_ptrshared_ptr或某些自定义资源管理器)。


1
在这里使用make_unique会更好。 - avernus
1
@avernus:我添加了一个注释,展示了make_unique的语法,但我认为在这种情况下这并不特别重要。 - Mr.C64
1
如果你遇到编译错误,你可能需要检查一下是否忘记了 public Base 部分。 - David

3
  • 使用unique_ptr来控制被分配资源的所有权,例如在函数内部分配到自由存储器上并返回一个unique_ptr

  • 如果所有权不是问题,仅使用引用来实现多态行为。即使unique_ptr可以做同样的事情,也可以让编译器少做额外的工作。

  • 如果所有权不是问题,在容器中使用指针来实现多态行为。你不能有一个引用的容器。


2

智能指针是关于所有权/生命周期的。在需要管理多态对象的生命周期时,请使用智能指针。如果只是使用该对象,请优先考虑原始引用/指针(按顺序)而非智能指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接