#include<iostream>#include<string_view>classBase{public:std::string_viewgetName()const{return"Base";}};classDerived:publicBase{public:std::string_viewgetName()const{return"Derived";}};intmain(){Derivedderived;Base&rBase{derived};std::cout<<"rBase is a "<<rBase.getName()<<'\n';return0;}
打印:
rBase is a Base
因为 rBase 是 Base 类型的引用,它会调用 Base::getName(),即便它实际上引用的是Derived类型中的Base部分。
#include<iostream>#include<string_view>classBase{public:virtualstd::string_viewgetName()const{return"Base";}// note addition of virtual keyword};classDerived:publicBase{public:virtualstd::string_viewgetName()const{return"Derived";}};intmain(){Derivedderived;Base&rBase{derived};std::cout<<"rBase is a "<<rBase.getName()<<'\n';return0;}
打印结果:
1
rBase is a Derived
因为 rBase 是 Derived 类型对象中 Base 部分的引用,因此当rBase.getName() 被调用时,它会解析为Base::getName()。不过,由于该函数是虚函数,所以程序会继续沿着派生的方向查找,如果在Base和Derived中存在该函数进一步派生的版本,则会调用该函数。在本例中,实际调用的是 Derived::getName()!
#include<iostream>#include<string_view>classA{public:virtualstd::string_viewgetName()const{return"A";}};classB:publicA{public:virtualstd::string_viewgetName()const{return"B";}};classC:publicB{public:virtualstd::string_viewgetName()const{return"C";}};classD:publicC{public:virtualstd::string_viewgetName()const{return"D";}};intmain(){Cc;A&rBase{c};//C类型中的A基类部分std::cout<<"rBase is a "<<rBase.getName()<<'\n';return0;}
#include<iostream>#include<string>#include<string_view>classAnimal{protected:std::stringm_name;// We're making this constructor protected because// we don't want people creating Animal objects directly,// but we still want derived classes to be able to use it.Animal(conststd::string&name):m_name{name}{}public:conststd::string&getName()const{returnm_name;}std::string_viewspeak()const{return"???";}};classCat:publicAnimal{public:Cat(conststd::string&name):Animal{name}{}std::string_viewspeak()const{return"Meow";}};classDog:publicAnimal{public:Dog(conststd::string&name):Animal{name}{}std::string_viewspeak()const{return"Woof";}};voidreport(constAnimal&animal){std::cout<<animal.getName()<<" says "<<animal.speak()<<'\n';}intmain(){Catcat{"Fred"};Dogdog{"Garbo"};report(cat);report(dog);return0;}
#include<iostream>#include<string>#include<string_view>classAnimal{protected:std::stringm_name;// We're making this constructor protected because// we don't want people creating Animal objects directly,// but we still want derived classes to be able to use it.Animal(conststd::string&name):m_name{name}{}public:conststd::string&getName()const{returnm_name;}virtualstd::string_viewspeak()const{return"???";}//虚函数};classCat:publicAnimal{public:Cat(conststd::string&name):Animal{name}{}virtualstd::string_viewspeak()const{return"Meow";}};classDog:publicAnimal{public:Dog(conststd::string&name):Animal{name}{}virtualstd::string_viewspeak()const{return"Woof";}};voidreport(constAnimal&animal){std::cout<<animal.getName()<<" says "<<animal.speak()<<'\n';}intmain(){Catcat{"Fred"};Dogdog{"Garbo"};report(cat);report(dog);return0;}
Catfred{"Fred"};Catmisty{"Misty"};Catzeke{"Zeke"};Doggarbo{"Garbo"};Dogpooky{"Pooky"};Dogtruffle{"Truffle"};// Set up an array of pointers to animals, and set those pointers to our Cat and Dog objectsAnimal*animals[]{&fred,&garbo,&misty,&pooky,&truffle,&zeke};for(constauto*animal:animals)std::cout<<animal->getName()<<" says "<<animal->speak()<<'\n';