在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
c++是面向对象语言,面向对象有个重要特点,就是继承和多态。继承之前学过了,就是一种重用类的设计方式。原有的类叫父类,或者基类,继承父类的类叫子类。在设计模式中,我们总是要避免继承,推荐用组合。因为继承会导致类爆炸。类太多了,就太累了。。。哈哈。。。 说说多态,多态,从我们语言的语法上说,就是通过父类的指针能直接调用子类的方法,在父类的层面,无需了解子类的实现。在我理解来看,其实多态,也是解耦的一种实现方式,因为子类的实现和父类没有关系了,父类总是可以调用到相关的函数。 但是如果我们父类有完整的一个实现,子类也有完整的实现,肿么办?父类肯定会调用自己的实现方法呀,一会我会讲解这个例子的。为了实现多态,c++语言引用了虚函数的概念。就是说,如果父类的某个函数是虚函数,那么好办,尽管你父类实现了这个虚函数也没关系,我通过指针调用的时候,我也会直接去找子类的相关实现,从而达到多态的效果。这个虚函数就有点像java里面的抽象方法了。但是留意细节哦....c++的虚函数,在父类也是可以实现的。我们来看一个完整的例子。 1 创建一个BaseClass.h的头文件,对父类BaseClass进行声明。
class BaseClass { protected: int x; int y; public: BaseClass(); BaseClass(int a,int b); void area(); };
#include <iostream> #include <string> #include "BaseClass.h" using namespace std; BaseClass::BaseClass() { x = 1; y = 2; } BaseClass::BaseClass(int a,int b) { x = a; y = b; } void BaseClass::area() { cout << "baseclass.area() call...." << endl; cout << x*y <<endl; }
#include "BaseClass.h" class DeriveClass1:public BaseClass { private: int z; public: void area(); void setValue(int a); DeriveClass1(); };
#include <iostream> #include "DeriveClass1.h" using namespace std; void DeriveClass1::area() { cout << "DeriveClass1.area() call...." << endl; cout << x*y*z << endl; } void DeriveClass1::setValue(int a) { z = a; } DeriveClass1::DeriveClass1() { z = 3; }
5 创建一个Main.cpp源文件,对以上的代码进行测试。
#include <iostream> #include "DeriveClass1.h" using namespace std; int main() { BaseClass *dc = new DeriveClass1(); dc->area(); return 1; }
7 这样一来,多态的效果达不到了么,为了达到多态,肿么办?我们将BaseClass.h头文件中的area函数声明为virtual即可,其他地方均不变。看代码,
class BaseClass { protected: int x; int y; public: BaseClass(); BaseClass(int a,int b); virtual void area(); };
这就是父类定义了虚函数的结果,尽管父类实现了该虚函数,但是父类的指针在指向子类的情况下,还是会调用子类对应的函数。 9 这个时候又出现一种情况,如果父类真的是没必要实现这个area函数肿么办??如果你就这样直接不实现,在连接的时候会报错,哈哈。BaseClass.cpp代码如下:
#include <iostream> #include <string> #include "BaseClass.h" using namespace std; BaseClass::BaseClass() { x = 1; y = 2; } BaseClass::BaseClass(int a,int b) { x = a; y = b; } void BaseClass::area();
--------------------Configuration: DeriveDemo - Win32 Debug-------------------- Compiling... BaseClazz.cpp Skipping... (no relevant changes detected) DeriveClass1.cpp Linking... BaseClazz.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall BaseClass::area(void)" (?area@BaseClass@@UAEXXZ) Debug/DeriveDemo.exe : fatal error LNK1120: 1 unresolved externals 执行 link.exe 时出错. DeriveDemo.exe - 1 error(s), 0 warning(s)
10 这个时候,纯虚函数就派上用场了,我们只需要将虚函数的定义后面赋值为0,即可。看看BaseClass.h头文件的定义。
class BaseClass { protected: int x; int y; public: BaseClass(); BaseClass(int a,int b); virtual void area()=0; };
12 纯虚函数和虚函数有什么区别,我们通过上面的定义可以看出: 虚函数定义:virtvual void area(); 纯虚函数的定义:virtual void area()=0; 虚函数,在父类中是必须实现的。 纯虚函数,在父类中是可以不用实现的。 熟悉java的同学发现这个有没有一点想抽象类和接口呀。哈哈。。
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论