C++ 继承
如何设计C++的类?子类和基类之间的关系?子类默认构造函数的初始化列表,多态性,虚构函数的应用?
//Object-Oriented
#include<iostream>
#include <string>
using namespace std;
class LibMat
{
public:
LibMat(){cout << "LibMat::LibMat default constructor!\n";}
virtual ~LibMat(){cout << "LibMat::~LibMat destructor!\n";}
virtual void print ()const
{
cout << "LibMat::print() -- I am a LibMat object! \n";
}
};
class Book : public LibMat
{
public:
Book(const string &title,const string &author):_title(title),_author(author)
{
cout<< "Book::Book (" << _title << "," << _author << ") constructor\n";
}
virtual ~Book(){cout<< "Book::~Book destructor\n";}
void print ()const
{
cout << "Book::print() -- I am a Book object! \n";
cout << "My title is : " << _title << endl;
cout << "My author is : "<< _author << endl;
}
const string & title(){return _title;}
const string &author(){return _author;}
protected:
string _title;
string _author;
};
class AudioBook : public Book
{
public:
AudioBook(const string &title,const string &author,const string &narrator):Book(title,author),_narrator(narrator)
{
cout<< "AudioBook::AudioBook (" << _title << "," << _author << "," << _narrator << ") constructor\n";
}
~AudioBook(){cout<< "AudioBook::~AudioBook destructor\n";}
void print ()const
{
cout << "AudioBook::print() -- I am a AudioBook object! \n";
cout << "My title is : " << _title << endl;
cout << "My author is : "<< _author << endl;
cout << "My narrator is : "<< _narrator << endl;
}
const string & narrator() const {return _narrator;}
//这里两个const,为何两个,用一个可以吗?当语句为string & narrator() const {return _narrator;}时,会提示编译错误,为何?return是const 而接收的却不是const,接收和返回的类型不匹配。
//为何要用两个const:简单的说为了防止改变私有成员的值。
private:
string _narrator;
};
void print(const AudioBook & audiobook)
{
cout << "in gobal print(): about to print mat.print()\n";
audiobook.print();
}
int main()
{
AudioBook ab("Mason and Dixon","Thomas Pynchon","Edwin Leonard");
print(ab);
//ab.narrator() = "hewei";
//cout <<"\n\n";
//print(ab);
}
上述代码的输出:
LibMat::LibMat default constructor!
Book::Book (Mason and Dixon,Thomas Pynchon) constructor
AudioBook::AudioBook (Mason and Dixon,Thomas Pynchon,Edwin Leonard) constructor
in gobal print(): about to print mat.print()
AudioBook::print() -- I am a AudioBook object!
My title is : Mason and Dixon
My author is : Thomas Pynchon
My narrator is : Edwin Leonard
AudioBook::~AudioBook destructor
Book::~Book destructor
LibMat::~LibMat destructor!
构造函数的调用顺序:在使用AudioBook的时候,会最先初始化基类的基类LibMat,调用它的构造函数,然后再初始化基类Book,最后在调用AudioBook的构造函数。
析构函数的调用顺序:和构造函数的调用顺序是相反的。
构造函数初始化列表:首先初始化最底层的基类,依次初始化。
多态性:子类为了实现自己独特的功能而屏蔽掉基类的功能,用virtual作为关键词修饰,类的每一个对象都与一个虚函数列表,程序在编译阶段并不会指定要调用哪个函数,只有在运行时通过查找各个虚函数类表,找出对应的函数。
比如上面的代码,AudioBook的函数print,当程序调用print时,会先查找ab对象的函数列表,发现Book 和 LibMat的print函数均是虚函数,则会调用ab自己的print函数。