按值和多态返回

时间:2013-07-02 16:55:49

标签: c++ polymorphism composition

所以我有一个存储类,它具有大量基本功能,非常有用。它有移动构造函数以允许按值返回。

class A
{
public:
    virtual ~A(){}
    A(const A& a);
    A(A&& a);
    A& operator=(const A& rhs);
    A& operator=(A&& rhs);
    int foo();//example member function
    //example function returning by value, elision and RHR make it efficient
    static A Foo();
};

这很棒,因为它允许拥有A的人定义得非常好。如果我开始需要继承扩展A的类,并且调用函数的return语句具有多态性,那么使用智能指针的唯一“正确”方法是什么? AKA

class B_interface : public A
{
public:
    virtual ~B_interface(){}
    virtual void FooBar() = 0;
};

class B : public B_interface
{
public:
    virtual ~B(){}
    B(const B& a);
    B(B&& a);
    B& operator=(const B& rhs);
    B& operator=(B&& rhs);
    virtual void FooBar() override;
    static shared_ptr<B> idontlikeit();
}

我想到了一种(可能是坏的)绕过它的方法:如果使用组合而不是继承:该类包含类似于impl ptr的东西:

class B_interface
{
public:
    virtual void FooBar() = 0;
};


class B : public A
{
    shared_ptr<B_interface> impl_;//could use 
public:
    B(const A& a,shared_ptr<B_interface> interface)//or some smarter way to pass this in
    : A(a)//call a's copy constructor
    {
       impl_.reset(interface);
    }//this constructor thinks

    void FooBar() { impl_->FooBar();}
    virtual ~B(){}
    B(const B& a);
    B(B&& a);
    B& operator=(const B& rhs);
    B& operator=(B&& rhs);
    static B ilikeitbetter();
}

所以我喜欢更好地使用那个类,但是让那个类变得有点臭...而且,B_interface在B之外可能没有多大意义......你们有其他选择吗?

1 个答案:

答案 0 :(得分:1)

是的,运行时多态性需要动态分配和指针。派生类可以(通常是)与基类大小不同,因此期望值语义的代码不知道为值类型保留的块大小。

在这种特定情况下,如果您不希望调用者需要共享语义,请考虑返回unique_ptr<Interface>。这样,如果调用者不需要,则不会强制调用者进行引用计数。 (如果用户希望共享语义,则始终可以将所有权从unique_ptr转移到shared_ptr