公私分明

应用场景

C++交付sdk库的时候,需要同时给出头文件。但是C++的类存在一个问题:private是类内部使用的,可能会包括不想暴露给用户的敏感成员函数和数据。但是对于C++来说,无论是public还是private,都是在头文件中定义的,没有办法做到公私分明。
libcamera关于Extensible/Private的设计模式,可以做到公私分明,很好地解决了这种问题。这里对这种设计模式做出一些介绍说明。
不过个人感觉,C++应该支持一个功能:把私有成员函数和成员变量写到cpp中,用private关键字说明,避免额外的设计。
 

Private和Extensible

class Private

class Private
{
public:
	Private() { _o = nullptr; };
	virtual ~Private();
	template<typename T>
	T *_o() { return static_cast<T *>(o_); }
private:
	friend class Extensible;
	Extensible *const o_;
};

这是一个保存私有成员的基类,它有以下特点:

  • 它的成员为Extensible *const o_,表示可以从private -> public,通过_o返回
  • Extensible类型的o_,是通过Extensible派生类的指针转化的
  • 模板化T *_o()表示返回的其实是Extensible的派生类;这里也可以直接返回Extensible,但是需要用户每次手动转化为派生类(如Camera)
  • 构造函数中初始化_o为nullptr,通过friend可以让class Extensible直接修改_o
  • 虚析构函数表示析构时,先析构派生类,再析构基类;这点和构造相反
     

class Extensible

class Extensible
{
public:
	Extensible(std::unique_ptr<Extensible::Private> d)
		: d_(std::move(d))
	{
		*const_cast<Extensible **>(&d_->o_) = this;
	}
protected:
	template<typename T>
	T *_d()
	{
		return static_cast<T *>(d_.get());
	}
private:
	const std::unique_ptr<Private> d_;

这是一个保存公共成员的基类,它有以下特点:

  • 它的成员为unique_ptr d_,表示可以从public -> private,通过_d返回
  • d_是保存公共成员的基类,模板化表示返回的其实是Private的派生类,也就是Camera::Private
  • 构造函数中,把this传给d_,与上面Private成员o_呼应,实现了public <--> private互访
     

Camera和Camera::Private1

class Camera::Private1

class Camera::Private1 : public Extensible::Private
{
	friend class Camera;
	...
}

先来看Private1,它有以下特点:

  • 这里取名Private1,为了区分Extensible::Private,Camera的私有类可以叫任意名
  • Camera继承了Extensible,Private1也要继承Private,这样Camera才可以借助Extensible/Private框架与Private1交互
     

class Camera

Class Camera: public Extensible
{
	Private1 *_d() { return Extensible::_d<Private1>(); }
	Camera(std::unique_ptr<Private1> d) : Extensible(std::move(d)) {}
}

Camera有以下特点:

  • 继承自Extensible,说明Camera is a Extensible
  • Camera将自己的私有类Private1传给Extensible,然后借助Extensible/Private框架与Private1交互
  • 这里的_d()覆盖基类的_d(),_d()可以叫任意名称 —— 所谓的成员函数覆盖,都可以不覆盖,另起名调用
     

libcamera源码获取

posted @ 2025-12-25 16:06  moonのsun  阅读(6)  评论(0)    收藏  举报