1.虚方法(Virsual Method)
析构器都是虚方法!从编译的角度看,他们只是普通的方法。如果他们不是虚方法,编译器就会根据他们在编译时的类型而调用那个在基类里定义的版本(构造器),那样往往会导致内存泄露!
class Pet { public: Pet(std::string theName); void eat(); void sleep(); virtual void play();//声明虚方法,解决子类在父类类型指针的情况下调用了父类的方法 protected: std::string name; }; class Dog:public Pet { public: Dog(std::string theName); void bark(); void play(); }; class Cat:public Pet { public: Cat(std::string theName); void climb(); void play(); }; Pet::Pet(std::string theName) { name = theName; } void Pet::eat() { std::cout << name << "正在吃东西!\n"; } void Pet::sleep() { std::cout << name << "正在睡大觉!\n"; } void Pet::play() { std::cout << name << "正在玩儿!\n"; } void Cat::climb() { std::cout << name << "正在爬树!\n"; } void Cat::play() { Pet::play(); std::cout << name << "玩毛线球!\n"; } void Dog::bark() { std::cout << name << "旺~旺~\n"; } void Dog::play() { Pet::play(); std::cout << name << "正在追赶那只该死的猫!\n"; } Cat::Cat(std::string theName):Pet(theName) { } Dog::Dog(std::string theName):Pet(theName) { } int main(int argc, const char * argv[]) { Pet *cat = new Cat("加菲"); Pet *dog = new Dog("欧迪"); //指针操作-> cat -> sleep(); cat -> eat(); cat -> play();//因为指针的类型是Pet,所以实际是调用Pet::play()方法 std::cout << std::endl; dog -> sleep(); dog -> eat(); dog -> play();//因为指针的类型是Pet,所以实际是调用Pet::play()方法 delete cat; delete dog; return 0; }
控制台返回的结果:
加菲正在睡大觉!
加菲正在吃东西!
加菲正在玩儿!
加菲玩毛线球!
欧迪正在睡大觉!
欧迪正在吃东西!
欧迪正在玩儿!
欧迪正在追赶那只该死的猫!
2.若没有声明虚方法的话,控制台返回的结果将会是:
加菲正在睡大觉!
加菲正在吃东西!
加菲正在玩儿!
欧迪正在睡大觉!
欧迪正在吃东西!
欧迪正在玩儿!
虚方法例子2
没有声明虚方法的时候
class animal { public: void sleep() { std::cout << "animal sleep " << std::endl; } void breathe() { std::cout << "animal breathe" << std::endl; } }; class fish:public animal { public: void breathe() { std::cout << "fish bubble " << std::endl; } }; int main(int argc, const char * argv[]) { fish fh; animal *pAn = &fh; pAn -> breathe();//是否声明成虚方法????? return 0; }
控制台返回的内容:
animal breathe
相反声明成虚方法了,控制台返回的结果会是:
fish bubble
2.所谓的多态,就是“一个接口,多种方法”。
3.抽象方法:抽象方法就是“纯虚方法”,其语法是“声明虚方法的同时,在其结尾加上”=0“。告诉编译器不用浪费时间在这个类里寻找这个方法的实现。
重载:overLoad
1.在同一个类中
2.函数名字相同
3.参数不同
4.virtual关键字可有可无
覆盖:overRide
1.位于派生类与基类
2.函数名字相同
3.参数相同
4.基类必须有virtual关键字
虚方法和抽象方法的区别:抽象方法不用实现。
class ClxBase { public: ClxBase() { }; virtual ~ClxBase()//基类析构器声明为虚函数的话,确保调用子类的析构器 { }; virtual void doSomething() { std::cout << "Do somehting in class ClxBase!\n"; } }; class ClxDerived:public ClxBase { public: ClxDerived() { }; ~ClxDerived() { std::cout << "Output from the destructor of class ClxDerived!\n"; }; void doSomething() { std::cout << "Do something in class ClxDerived!\n"; }; }; int main(int argc, const char * argv[]) { ClxBase *pTest = new ClxDerived; pTest -> doSomething(); delete pTest; return 0; }
c++第八章-(虚方法与抽象方法),布布扣,bubuko.com
原文地址:http://www.cnblogs.com/huen/p/3824445.html