当前位置:编程学习 > C/C++ >>

C++ 多重继承介绍

1.1. 多重继承
多重继承是指一个类具继承自多个父类,如果这多个基类中具有同名的成员,则在派生类中引用这具有重名的成员时必须使用域作用符标识,否则编译器将无法知道引用的是哪一个变量。

#include
class BaseA { protected: int _mem; };
class BaseB { protected: int _mem; };
class Derived : public BaseA, public BaseB
{
public:
Derived(int a, int b) { BaseA::_mem = a, BaseB::_mem = b; }
inline int A( void ) const { return BaseA::_mem; }
inline int B( void ) const { return BaseB::_mem; }
};

int main( void )
{
Derived d(1, 2);
std::cout<<"A="<
Print(readme);
Dispose(readme);
delete readme;
}

1.1.2. Base-From-Member用法
在boost中使用多种继承解决一种叫base-from-member的问题[6] :即基类通过构造函数初始化时用到派生类的成员变量的情况。因为派生类的构造在基类构造之后,派生类的成员在所有基类构造函数执行之后才会被构造,如果其类的构造函数对派生类的成员进行操作,结构则不可预知,C 标准未定义。例如:
#include // for std::streambuf
#include // for std::ostream
class fdoutbuf : public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};

class fdostream : public std::ostream
{
protected:
fdoutbuf buf;
public:
explicit fdostream( int fd ) : buf( fd ), std::ostream( &buf )
{}
//...
};

所以,必须采用一定技术保证程序不会对未完成构造的对象进行操作。 R. Samuel Klatchko采用另外定义一个基类的方法解决这个问题,因为其类的构造顺序与定义时的顺序相同,只要把基类用到的成员的定义放到另一个基类中,并把它放到定义列表的前面。例如:

#include // for std::streambuf
#include // for std::ostream
class fdoutbuf : public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};

struct fdostream_pbase
{
fdoutbuf sbuffer;
explicit fdostream_pbase( int fd ) : sbuffer( fd )
{}

};

class fdostream : private fdostream_pbase , public std::ostream
{
typedef fdostream_pbase pbase_type;
typedef std::ostream base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &sbuffer )
{}
//...
};

这种情况下的多重继承并不是必须的,此前,笔者在一个项目中处理这种问题的方法是使用指针,该指针所指向的对象在初始化列表时使用new创建,代码如下。因为在调用ostream的构造函数时,其实参为一个赋值表达式,赋值表达式必定先被执行,这样_content最先被初始化,因为指针是POD类型,这样做也是安全的。需要注意的是ostream的构造函数可能会抛出异常,因为此时 TDTPMessage对象并没有被成功构造,所以析构函数也不会被执行,那么content_指向的对象可能会造成内存泄漏,所以必须使用代码中的函数 try块(function-try-block)捕捉基类构造函数可能抛出的异常。

#include
class TDTPMessage : public ostream
{
public:
TDTPMessage( void )
try
:ostream( content_ = new stringbuf())
{ /* ... */ }
catch(...){
if( content_ != NULL) delete content_;
/* ... */
throw;
}
~TDTPMessage( void ) { if( content_ != NULL) delete content_; }
private:
std::stringbuf* content_;
};
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,