当我遇到这种情况时,我正在学习 C++,我想在 C++ 中实现以下 C 符号代码的等效有效版本。
<header.h>
struct Obj;
Obj* create(...);
void do_some_thing(Obj*);
void do_another_thing(Obj*);
void destroy(Obj*);
要求是:
- 该实现在库(静态/动态)中提供,并且标头不公开除接口以外的任何细节
- 它应该同样有效
使用虚函数公开接口(类 COM)是不合格的;这是一种启用多态性(通过同一接口公开多个实现)的解决方案,但事实并非如此,而且由于我不需要它带来的价值,我不明白为什么我应该支付调用函数的成本通过2个间接指针。所以我的下一个想法是 pimpl 成语:
<header.h>
class Obj {
public:
Obj();
~Obj();
void do_some_thing();
void do_another_thing();
private:
class Impl;
smart_ptr<Impl> impl_; // ! What should I use here, unique_ptr<> or shared_ptr<> ?
};
shared_ptr<> 似乎不符合条件,我会为原始实现中不存在的不必要的互锁递增/递减付费。另一方面, unique_ptr<> 使 Obj 不可复制。这意味着客户端不能调用他自己的函数来获取 Obj 的值,而 Obj 只是一个指针的包装器,所以本质上他不能通过值传递指针!他可以在原始版本中做到这一点。(通过引用传递仍然不合格:他仍在传递指向指针的指针)
那么在 C++ 中实现这一点的同样有效的方法应该是什么?
编辑:我给了它更多的想法,我来到了这个解决方案:
<header.h>
class ObjRef // I exist only to provide an interface to implementation
{ // (without virtual functions and their double-level indirect pointers)
public:
ObjRef();
ObjRef(ObjRef); // I simply copy pointers value
ObjRef operator=(ObjRef); // ...
void do_some_thing();
void do_another_thing();
protected:
class Impl;
Impl* impl_; // raw pointer here, I'm not responsible for lifetime management
};
class Obj : public ObjRef
{
Obj(Obj const&); // I'm not copyable
Obj& operator=(Obj const&); // or assignable
public:
Obj(Obj&&); // but I'm movable (I'll have to implement unique_ptr<> functionality)
Obj& operator=(Obj&&);
Obj();
~Obj(); // I destroy impl_
// and expose the interface of ObjRef through inheritance
};
现在我回到客户端Obj,如果客户端需要通过调用他的一些其他函数来分配Obj的使用,他可以将它们声明为
void use_obj(ObjRef o);
// and call them:
Obj o = call_my_lib_factory();
use_obj(o);