所以我有一个存储类,它具有大量基本功能,非常有用。它有移动构造函数以允许按值返回。
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之外可能没有多大意义......你们有其他选择吗?
答案 0 :(得分:1)
是的,运行时多态性需要动态分配和指针。派生类可以(通常是)与基类大小不同,因此期望值语义的代码不知道为值类型保留的块大小。
在这种特定情况下,如果您不希望调用者需要共享语义,请考虑返回unique_ptr<Interface>
。这样,如果调用者不需要,则不会强制调用者进行引用计数。 (如果用户希望共享语义,则始终可以将所有权从unique_ptr
转移到shared_ptr