update
This commit is contained in:
41
basic_content/c_poly/README.md
Normal file
41
basic_content/c_poly/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# C实现C++的面向对象特性
|
||||
|
||||
## 关于作者:
|
||||
|
||||
个人公众号:
|
||||
|
||||

|
||||
|
||||
## 1.C++实现案例
|
||||
|
||||
C++中的多态:在C++中会维护一张虚函数表,根据赋值兼容规则,我们知道父类的指针或者引用是可以指向子类对象的。
|
||||
|
||||
如果一个父类的指针或者引用调用父类的虚函数则该父类的指针会在自己的虚函数表中查找自己的函数地址,如果该父类对象的指针或者引用指向的是子类的对象,而且该子类已经重写了父类的虚函数,则该指针会调用子类的已经重写的虚函数。
|
||||
|
||||
学习案例代码见:[c++_examp.cpp](./c++_examp.cpp)
|
||||
|
||||
|
||||
|
||||
## 2.C实现
|
||||
|
||||
- 封装
|
||||
|
||||
C语言中是没有class类这个概念的,但是有struct结构体,我们可以考虑使用struct来模拟;
|
||||
|
||||
使用函数指针把属性与方法封装到结构体中。
|
||||
|
||||
- 继承
|
||||
|
||||
结构体嵌套
|
||||
|
||||
- 多态
|
||||
|
||||
类与子类方法的函数指针不同
|
||||
|
||||
在C语言的结构体内部是没有成员函数的,如果实现这个父结构体和子结构体共有的函数呢?我们可以考虑使用函数指针来模拟。但是这样处理存在一个缺陷就是:父子各自的函数指针之间指向的不是类似C++中维护的虚函数表而是一块物理内存,如果模拟的函数过多的话就会不容易维护了。
|
||||
|
||||
模拟多态,必须保持函数指针变量对齐(在内容上完全一致,而且变量对齐上也完全一致)。否则父类指针指向子类对象,运行崩溃!
|
||||
|
||||
|
||||
|
||||
学习案例代码见:[c_examp.c](./c_examp.c)
|
BIN
basic_content/c_poly/c++_examp
Executable file
BIN
basic_content/c_poly/c++_examp
Executable file
Binary file not shown.
42
basic_content/c_poly/c++_examp.cpp
Normal file
42
basic_content/c_poly/c++_examp.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file c++_examp.cpp
|
||||
* @brief c++中的多态
|
||||
* @author 光城
|
||||
* @version v1
|
||||
* @date 2019-08-06
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
class A
|
||||
{
|
||||
public:
|
||||
virtual void f()//虚函数实现
|
||||
{
|
||||
cout << "Base A::f() " << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B:public A // 必须为共有继承,否则后面调用不到,class默认为私有继承!
|
||||
{
|
||||
public:
|
||||
virtual void f()//虚函数实现,子类中virtual关键字可以没有
|
||||
{
|
||||
cout << "Derived B::f() " << endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
A a;//基类对象
|
||||
B b;//派生类对象
|
||||
|
||||
A* pa = &a;//父类指针指向父类对象
|
||||
pa->f();//调用父类的函数
|
||||
|
||||
pa = &b; //父类指针指向子类对象,多态实现
|
||||
pa->f();//调用派生类同名函数
|
||||
return 0;
|
||||
}
|
BIN
basic_content/c_poly/c_examp
Executable file
BIN
basic_content/c_poly/c_examp
Executable file
Binary file not shown.
55
basic_content/c_poly/c_examp.c
Normal file
55
basic_content/c_poly/c_examp.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file c_examp.c
|
||||
* @brief C实现多态
|
||||
* @author 光城
|
||||
* @version v1
|
||||
* @date 2019-08-06
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/// 重定义一个函数指针类型
|
||||
typedef void (*pf) ();
|
||||
|
||||
/**
|
||||
* @brief 父类
|
||||
*/
|
||||
typedef struct _A
|
||||
{
|
||||
pf _f;
|
||||
}A;
|
||||
|
||||
|
||||
/**
|
||||
* @brief 子类
|
||||
*/
|
||||
typedef struct _B
|
||||
{
|
||||
A _b; ///< 在子类中定义一个基类的对象即可实现对父类的继承。
|
||||
}B;
|
||||
|
||||
void FunA()
|
||||
{
|
||||
printf("%s\n","Base A::fun()");
|
||||
}
|
||||
|
||||
void FunB()
|
||||
{
|
||||
printf("%s\n","Derived B::fun()");
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
A a;
|
||||
B b;
|
||||
|
||||
a._f = FunA;
|
||||
b._b._f = FunB;
|
||||
|
||||
A *pa = &a;
|
||||
pa->_f();
|
||||
pa = (A *)&b; /// 让父类指针指向子类的对象,由于类型不匹配所以要进行强转
|
||||
pa->_f();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user