〔对象与备户之间的连接间题 客卢与C++对象之间的连接点越小越好 只有接口部分必要的信息才放入接口 把C++类的实现细节与接口分开 提取出针对所有编译器都不变的因素作为 客户与对象共享的接口信息 冷方案1:句柄
C++对象与客户之间的 对象与客户之间的连接问题 !客户与C++对象之间的连接点越小越好 – 只有接口部分必要的 只有接口部分必要的信息才放入接口 – 把C++类的实现细节与接口分开 – 提取出针对所有编译器都不变的因素作为 客户与对象共享的接口信息 !方案1:句柄
句柄方案 #ifndef CMyString class CMystring 方案1句柄#ndt class EXPORTORIMPORT IMyString class CMyString private private CMy m pthis char m psz public int m nLength public IMy String(const char * psz) CMy String(const char*psz) -IMy( CMyStringO const char* Find( const char *psz) const char*Find const char"psz); int Length int Length(;
句柄方案 !方案 1 :句柄 #ifndef CMyString class CMyString; #endif class EXPORTORIMPORT IMyString { private: CMyString *m_pthis; public: IMyString(const char * psz); ~IMyString(); const char*Find(const char *psz); int Length(); }; class CMyString { private: char *m_psz; int m_nLength; public: CMyString(const char * psz); ~CMyString(); const char*Find(const char *psz); int Length(); };
纯虚基类方案 提条件 在给定平台上所有的编译器都会产生同 样的二进制结构 纯虚函数在单继承情况下满足这一条件 纯虚基类只包含虚函数,限定每个虚 函数的调用习惯 冷对于跨平台的情形,我们肯定要通过 中间层,所以暂时可以不考虑
纯虚基类方案 !前提条件: – 在给定平台上所有的编译器 在给定平台上所有的编译器都会产生同 样的二进制结构 – 纯虚函数在单继承情况下满足 单继承情况下满足这一条件 !纯虚基类只包含虚函数,限定每个虚 虚基类只包含虚函数,限定每个虚 函数的调用习惯 !对于跨平台的情形,我们肯定要通过 中间层,所以暂时可以不考虑
虚函数的继承布局情况 变量偏移量 Class B: pulic A alue 0 int value 1 vtable blic virtual void Funcl(void) B: Func1 B: Func2 virtual void FunC2(void) alue }
虚函数的继承布局情况 class B : class B : pulic A { private : private : int value1; value1; public: public: virtual void Func1(void) virtual void Func1(void) virtual void Func2(void) virtual void Func2(void) }; 变量 偏移量 value 0 vptr 4 value1 8 B::Func1 B::Func2 vtable
纯虚基类方案例子 解决了名字冲突 解决了C++类的二进制布局不兼容间题 客户只看到 vtable,没有看到其他的实现细节 倮证不同语言编写的程序可以互操作 在不改变接口的情况下,可以单独升级客户或者对象 class IString virtual const char*Find( const char/变量|偏移 vtable virtual int Length=0 Length
纯虚基类方案例子 ! 解决了名字冲突 解决了名字冲突 ! 解决了C++类的二进制布局不兼容问题 – 客户只看到vtable,没有看到其他的实现细节 – 保证不同语言编写的程序可以互操作 – 在不改变接口的情况下,可以单独升级客户或者对象 class IString { virtual const char*Find(const char *psz)=0; virtual int Length()=0; }; 变量 偏移量 vptr 4 Find Length vtable