首页 > 代码库 > 引用对象做向上转换,但对虚函数不影响使用

引用对象做向上转换,但对虚函数不影响使用

//: WIND2.CPP -- Inheritance & upcasting
#include <iostream.h>
enum note { middleC, Csharp, Cflat }; // Etc.

class instrument {
public:
    void play(note) const { // 不是虚函数
        cout << "instrument::play" << endl;
    }
};

class wind : public instrument {
public:
    void play(note) const {
        cout << "wind::play" << endl;
    }
};

void tune(instrument& i) { // 引用对象不会造成切片
    i.play(middleC);
}

main() {
    wind flute;  // tune要求父类的引用对象,但这里定义的是子类对象
    tune(flute); // 可以传递子类,但做了向上转换Upcasting,因为不是虚函数,所以调用父类函数。
}

运行结果:instrument::play

 

//: WIND3.CPP -- Late binding with virtual
#include <iostream.h>
enum note { middleC, Csharp, Cflat }; // Etc.

class instrument {
public:
  virtual void play(note) const { // 虚函数
    cout << "instrument::play" << endl;
  }
};

// Wind objects are instruments
// because they have the same interface:
class wind : public instrument {
public:
  // Redefine interface function:
  void play(note) const {
    cout << "wind::play" << endl;
  }
};

void tune(instrument& i) {
  // ...
  i.play(middleC);
}

main() {
  wind flute;
  tune(flute); // 可以传递子类,但做了向上转换Upcasting,因为是虚函数,所以调用子类函数。
}

运行结果:wind::play

//: SLICE.CPP -- Object slicing
#include <iostream.h>

class base {
  int i;
public:
  base(int I = 0) : i(I) {}
  virtual int sum() const { return i; }
};

class derived : public base {
  int j;
public:
  derived(int I = 0, int J = 0)
    : base(I), j(J) {}
  int sum() const { return base::sum() + j; }
};

void call(base b) {
  cout << "sum = " << b.sum() << endl;
}  
    
main() {
  base b(10);
  derived d(21, 47);
  call(b);
  call(d); // 产生切片以后,就算是调用虚函数也没有用,仍然使用父类的函数进行计算,计算的时候当然使用父类的数据成员
}  

输出结果:

sum = 10
sum = 21