//ModuleBase.h
class ModuleBase
{
public:
ModuleBase();
ModuleBase(ModuleBase* _impl);
virtual ~ModuleBase() {}
//省略了很多方法声明。比如开启定时器的函数声明、通过传一个 lambda 表达式来起一个异步的任务
private:
android::sp<ModuleBase> impl;
};
项目里写了一个框架,每个子模块都可以直接继承 ModuleBase 来使用定时器等功能,比如class ModuleA : public ModuleBase
。
//ModuleBaseImpl.h
class ModuleBaseImpl : public ModuleBase
{
public:
ModuleBaseImpl(ModuleBase& owner);
virtual ~ModuleBaseImpl();
//省略了很多方法声明。比如开启定时器的函数声明、通过传一个 lambda 表达式来起一个异步的任务
private:
ModuleBase& mOwner;
};
ModuleBaseImpl 则是模块通用功能的真正实现。
// ModuleBase 的实现
ModuleBase::ModuleBase()
: impl(new ModuleBaseImpl(*this)) {
}
ModuleBase::ModuleBase(ModuleBase* _impl)
: impl(_impl) {
}
// ModuleBaseImpl 的实现
ModuleBaseImpl::ModuleBaseImpl(ModuleBase& owner)
: ModuleBase(this),
mOwner(owner)
{
}
上面我省略了很多函数的实现,实际上,ModuleBase 的很多函数都是通过它的android::sp<ModuleBase> impl
成员来间接调用的,因为真正的实现都在 ModuleBaseImpl ,比如:
void ModuleBase::startTimer(int32_t timerId, uint64_t msec) {
if (NULL != impl.get()) {
static_cast<ModuleBaseImpl*>(impl.get())->startTimer(timerId, msec);
}
}
目前看来,这么写是为了隐藏 ModuleBaseImpl 的实现,使用者原则上只需要 include ModuleBase.h 即可,但这么写是一种比较好的写法吗?(而且理解起来比较费心智)
class ModuleA : public ModuleBase{};
ModuleA a;
比如上面这个,执行了ModuleA a;
实际上生成了两个对象,第一个是我们能看到的 a 对象。第二个是ModuleBase::ModuleBase(): impl(new ModuleBaseImpl(*this)) {}
里生成的 ModuleBaseImpl 对象(因为子模块 ModuleA 总是隐式地去调用父类 ModuleBase 的默认构造函数),但是使用者感觉不到这个 ModuleBaseImpl 对象的存在。
而且是:a 对象通过 sp 指针来指向这个隐藏 ModuleBaseImpl 对象,这个隐藏 ModuleBaseImpl 对象通过 owner 引用来指向 a 对象。(理解起来好费脑细胞啊)
(很尽力描述清楚了 QAQ )
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.