程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 多重繼承中的純虛函數“妙用”

多重繼承中的純虛函數“妙用”

編輯:C++入門知識

在多重繼承中,處於中間層的類可能有一些用,但又不會實例化。在最終實現類中需要調用中間類的方法,同時必須保證在最終類中也實現該方法。如何做到?

說的不清晰,舉OceanBase的例子吧:

ObPhyOperator是一個純虛基類,它要求每一個子類都實現reset()方法:


[cpp] view plaincopyprint?class ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 

class ObPhyOperator
{
  public:
  virtual void reset() = 0;
};


ObSingleChildPhyOperator從ObPhyOperator繼承過來,是所有“Single child Operator"的父類,它有一個成員”child_op_"。一些情況下為了能夠重用operator,在set_child之前需要調用reset重置child_op_狀態為NULL:


[cpp]
class ObSingleChildPhyOperator : public ObPhyOperator 

  public: 
    int set_child(ObPhyOperator *op); 
    virtual void reset() = 0;  // 注意這個 "=0" !!!!  
 
  private: 
    ObPhyOperator *child_op_; 
}; 
 
int ObSingleChildPhyOperator::set_child(ObPhyOperator *op) 

  if (NULL != child_op_) 
  { 
     TBSYS_LOG(WARN, "operator already inited!"); 
     return OB_ERROR; 
  } 
  child_op_ = op; 
  return OB_SUCCESS; 

 
void ObSingleChildPhyOperator::reset() 

  child_op_ = NULL; 

class ObSingleChildPhyOperator : public ObPhyOperator
{
  public:
    int set_child(ObPhyOperator *op);
    virtual void reset() = 0;  // 注意這個 "=0" !!!!

  private:
    ObPhyOperator *child_op_;
};

int ObSingleChildPhyOperator::set_child(ObPhyOperator *op)
{
  if (NULL != child_op_)
  {
     TBSYS_LOG(WARN, "operator already inited!");
     return OB_ERROR;
  }
  child_op_ = op;
  return OB_SUCCESS;
}

void ObSingleChildPhyOperator::reset()
{
  child_op_ = NULL;
}ObFinalOperator繼承自ObSingleChildPhyOperator,我們要求它一定有一個reset()方法,用於管理operator的內部狀態,如內存、基本參數等。如何做到“一定”呢?上面ObSingleChildPhyOperator的


[cpp]
virtual void reset() = 0;  // 注意這個 "=0" !!!! 

    virtual void reset() = 0;  // 注意這個 "=0" !!!!
保證了這一點。如果沒有“=0”,即使ObFinalOperator不實現reset()方法,語法上也不會報錯,給代碼維護帶來困難。

 

 

 


下面通過一個實驗來一步步學習這個技巧。

 


下面的代碼能夠編譯通過嗎?


[cpp]
#include <iostream>     /* cin, cout */  
using namespace std; 
 
class ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
class ObSingleChildPhyOperator : public ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
class ObFinalOperator: public ObSingleChildPhyOperator 

  public: 
}; 
 
int main() 

  ObPhyOperator *phy = new ObFinalOperator(); 
  return 0; 

#include <iostream>     /* cin, cout */
using namespace std;

class ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

class ObSingleChildPhyOperator : public ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

class ObFinalOperator: public ObSingleChildPhyOperator
{
  public:
};

int main()
{
  ObPhyOperator *phy = new ObFinalOperator();
  return 0;
}

報錯如下:


[plain]
virtual_structure.cpp: In function ‘int main()’: 
virtual_structure.cpp:54: error: cannot allocate an object of abstract type ‘ObFinalOperator’ 
virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’: 
virtual_structure.cpp:31: note:         virtual void ObSingleChildPhyOperator::reset() 

virtual_structure.cpp: In function ‘int main()’:
virtual_structure.cpp:54: error: cannot allocate an object of abstract type ‘ObFinalOperator’
virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’:
virtual_structure.cpp:31: note:         virtual void ObSingleChildPhyOperator::reset()
OK,為ObSingleChildPhyOperator加上reset實現呢?


[cpp]
#include <iostream>     /* cin, cout */  
using namespace std; 
 
/// Base virtual class ObPhyOperator  
class ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
/// Middle virtual class ObSingleChildPhyOperator  
class ObSingleChildPhyOperator : public ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
void ObSingleChildPhyOperator::reset() 

  cout << "single" << endl; 

 
/// ObFinalOperator  
class ObFinalOperator: public ObSingleChildPhyOperator 

  public: 
}; 
 
int main() 

  ObPhyOperator *phy = new ObFinalOperator(); 
  return 0; 

#include <iostream>     /* cin, cout */
using namespace std;

/// Base virtual class ObPhyOperator
class ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

/// Middle virtual class ObSingleChildPhyOperator
class ObSingleChildPhyOperator : public ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

void ObSingleChildPhyOperator::reset()
{
  cout << "single" << endl;
}

/// ObFinalOperator
class ObFinalOperator: public ObSingleChildPhyOperator
{
  public:
};

int main()
{
  ObPhyOperator *phy = new ObFinalOperator();
  return 0;
}

報錯依舊:


[cpp]
virtual_structure.cpp: In function ‘int main()’: 
virtual_structure.cpp:52: error: cannot allocate an object of abstract type ‘ObFinalOperator’ 
virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’: 
virtual_structure.cpp:45: note:         virtual void ObSingleChildPhyOperator::reset() 

virtual_structure.cpp: In function ‘int main()’:
virtual_structure.cpp:52: error: cannot allocate an object of abstract type ‘ObFinalOperator’
virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’:
virtual_structure.cpp:45: note:         virtual void ObSingleChildPhyOperator::reset()
看來,必須在ObFinalOperator中實現reset方法:


[cpp]
#include <iostream>     /* cin, cout */  
using namespace std; 
 
/// Base virtual class ObPhyOperator  
class ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
/// Middle virtual class ObSingleChildPhyOperator  
class ObSingleChildPhyOperator : public ObPhyOperator 

  public: 
  virtual void reset() = 0; 
}; 
 
void ObSingleChildPhyOperator::reset() 

  cout << "single" << endl; 

 
/// ObFinalOperator  
class ObFinalOperator: public ObSingleChildPhyOperator 

  public: 
    virtual void reset(); 
}; 
 
 
void ObFinalOperator::reset() 

  cout << "final" << endl; 
  // ObSingleChildPhyOperator::reset();  

 
 
int main() 

  ObPhyOperator *phy = new ObFinalOperator(); 
  return 0; 

#include <iostream>     /* cin, cout */
using namespace std;

/// Base virtual class ObPhyOperator
class ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

/// Middle virtual class ObSingleChildPhyOperator
class ObSingleChildPhyOperator : public ObPhyOperator
{
  public:
  virtual void reset() = 0;
};

void ObSingleChildPhyOperator::reset()
{
  cout << "single" << endl;
}

/// ObFinalOperator
class ObFinalOperator: public ObSingleChildPhyOperator
{
  public:
    virtual void reset();
};


void ObFinalOperator::reset()
{
  cout << "final" << endl;
  // ObSingleChildPhyOperator::reset();
}


int main()
{
  ObPhyOperator *phy = new ObFinalOperator();
  return 0;
}

編譯通過,bingo~

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved