C++ 面向对象设计及多态说明

一、概念

面向对象是数据抽象、继承、动态绑定。

数据抽象,可以实现类接口与实现分离;

继承,派生类可以继承基类;

动态绑定,由于存在派生类和基类的继承函数,在实际运行时,会根据传递的实参选择函数的版本,以此实现运行时绑定。

 

1.基类

基类中通常应该定义一个虚析构函数。

虚函数:派生类可以通过其成员函数覆盖基类的函数。

基类中定义了静态成员,则整个继承体系只存在该成员的唯一定义。

class base {
public:
  base() = default;
  virtual ~base() = default;
  virtual void print() {
    std::cout << "This is base!" << std::endl;
  }
  static void hello() { std::cout << "hello!" << std::endl;}
}; 

2.派生类

派生类继承基类

派生类中函数覆盖了基类中的函数时,可以使用virtual说明也可以不用。

class Derived:public base {
  Derived() = default;
  void print () {
    std::cout << "This id Derived!" << std::endl;
};

3.final 和override说明符

final 关键字加在函数后面,显示的表示不允许其他类覆盖此函数;

ovriride 关键字加在派生类函数后面,显示的说明该函数继承基类的虚函数,当派生类函数的形参没有和基类的一样时,会提示报错。

代码段 小部件

4.抽象基类和纯虚函数

基类中如果只定义函数接口,具体实现都在派生类中继承,则可以定义纯虚函数。

含有纯虚函数的基类称为抽象基类,抽象基类不可以直接创建,可以创建其派生类。

代码段 小部件

5.public protected private

public:没有限制的访问,外部成员也能访问;

protected:类自己的成员函数以及派生类的成员函数可以访问;

private:只有类自己成员函数可以访问。

class test_protest {
public:
  void pub_men();
protected:
  int prot_men;
private:
  char priv_men;
};

class test_pri:test_protest {
public:
  int f() {return prot_men;}  // 可以访问protected成员
};

6.虚函数与作用域

若基类和派生类的实参不同,则无法通过基类的引用或者指针调用派生类的虚函数。

class base {
public:
  virtual int fcn() {return 0;};
};

class D1:public base {
public:
  int fcn(int) {return 1;};
  virtual void f2() {std::cout << "D1->f2" << std::endl;};
};

class D2:public D1 {
public:
  int fcn(int);
  int fcn() {retrun 2;};
  void f2() {std::cout << "D2->f2" << std::endl;};
};

int main(int argc, char** argv) {
  base obj;
  D1 d1obj;
  D2 d2obj;
  base *bp1 = &obj, *bp2 = &d1obj, *bp3 = &d2obj;
  bp1->fcn();  //base::fcn
  bp2->fcn();  //base::fcn
  bp3->fcn();  //D2::fcn
  D1 *d1p = &d1obj;
  D2 *d2p = &d2obj;
  d1p->f2();
  d2p->f2();
};

7.虚析构函数

当delete一个动态分配的对象的指针时将执行析构函数。虚析构函数的虚属性也会被继承。派生类使用合成的析构函数还是自己的析构函数,都是虚函数,因此当delete基类的指针时将运行正确的析构函数。

如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义行为。

当类中没有定义析构函数时,编译器会生成一个什么都不做的析构函数,默认生成的析构函数是普通的析构函数不是虚函数。所以基类要显示的定义虚析构函数。

class base {
public:
  virtual  ~base = default;
  virtual int fcn() {return 0;};
};

class D1:public base {
public:
  ~base = default;
  int fcn(int) {return 1;};
  virtual void f2() {std::cout << "D1->f2" << std::endl;};
};

int main (int argc, char** argv) {
  base *bp = new base; //静态与动态一致
  delete bp;  //调用base的析构函数
  bp = new D1;  //静态类型与动态类型不一致
  delete bp;  //调用D1的析构函数
  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值