美文网首页
C语言实现面向对象

C语言实现面向对象

作者: ShowMeCoding | 来源:发表于2023-04-12 23:11 被阅读0次

一步步分析:C语言如何面向对象编程 - 知乎 (zhihu.com)
C 语言实现面向对象编程_面向对象程序设计c语言_onlyshi的博客-CSDN博客

Animal.h

#ifndef _ANIMAL_H_
#define _ANIMAL_H_

//父类虚表的前置声明
struct AnimalVTable;

// 定义父类结构
typedef struct {
    struct AnimalVTable* vptr; //虚表指针
    int age;
    int weight;
} Animal;

// 构造函数声明
//显示定义this指针,当调用时主动把对象的地址传递给它
void Animal_Ctor(Animal* this, int age, int weight); 

//父类中的虚表
struct AnimalVTable {
    void (*say)(Animal* this); //虚函数指针
};

//父类中实现的虚函数
void Animal_Say(Animal* this);

// 获取父类属性声明
int Animal_GetAge(Animal* this);
int Animal_GetWeight(Animal* this);

#endif

Animal.c

#include "assert.h"
#include "Animal.h"

//父类中虚函数的具体实现
static void _Animal_Say(Animal* this) {
    //因为父类中Animal是一个抽象的东西,不该被实例化
    //父类中的虚函数不应该被调用,也就是说子类必须实现这个虚函数
    //类似于C++中的纯虚函数
    assert(0);
}

// 父类构造函数实现
void Animal_Ctor(Animal* this, int age, int weight)
{
    //首先定义一个虚表
    static struct AnimalVTable animal_vtbl = { _Animal_Say };
    //让虚指针指向上面这个虚表
    this->vptr = &animal_vtbl;
    this->age = age;
    this->weight = weight;
}

//测试多态
void Animal_Say(Animal* this) {
    //如果this实际指向一个子类Dog对象,那么this->vptr这个虚表指针指向子类自己的虚表
    //因此,this->vptr->say将会调用子类虚表中的函数
    this->vptr->say(this);
}

int Animal_GetAge(Animal* this)
{
    return this->age;
}

int Animal_GetWeight(Animal* this)
{
    return this->weight;
}

Dog.h

#ifndef _DOG_H_
#define _DOG_H_

#include "Animal.h"
//定义子类结构
typedef struct {
    Animal parent; //第一个位置放置父类结构
    int legs;      //定义子类属性
} Dog;

//子类构造函数声明
void Dog_Ctor(Dog* this, int age, int weight, int legs);

//子类属性声明
int Dog_GetAge(Dog* this);
int Dog_GetWeight(Dog* this);
int Dog_GetLegs(Dog* this);

#endif

Dog.c

#include "Dog.h"

//子类中虚函数的具体表现
static void _Dog_Say(Dog* this) {
    printf("dog say hello!\n");
}

//子类构造函数
void Dog_Ctor(Dog* this, int age, int weight, int legs) {
    //首先调用父类构造函数,初始化从父类继承的数据
    Animal_Ctor(&this->parent, age, weight);
    //定义子类自己的虚函数表
    static struct AnimalVTable dog_vtbl = { _Dog_Say };
    //把从父类中继承得到的虚表指针指向子类自己的虚表
    this->parent.vptr = &dog_vtbl;
    //然后初始化子类自己的数据
    this->legs = legs;
}


//子类构造函数声明
int Dog_GetAge(Dog* this) {
    //age属性是继承而来,转发给父类中的获取属性函数
    return Animal_GetAge(&this->parent);
}
int Dog_GetWeight(Dog* this) {
    return Animal_GetWeight(&this->parent);

}
int Dog_GetLegs(Dog* this) {
    //直接返回子类的属性
    return this->legs;
}

main.c

#include <stdio.h>
#include "Animal.h"
#include "Dog.h"

int main() {
    //封装:描述数据的组织形式,把一个对象的所有属性组织在一起,c语言使用结构体
    //在栈上创建一个对象
    Animal a;
    //构造对象
    Animal_Ctor(&a, 1, 3);
    printf("age = %d, weight = %d \n",
        Animal_GetAge(&a),
        Animal_GetWeight(&a));

    //继承:子类通过继承父类,自动拥有父类的属性和方法,c语言主要注意内存模型
    Dog d;
    Dog_Ctor(&d, 1, 3, 4);
    printf("age = %d, weight = %d, legs = %d \n",
        Dog_GetAge(&d),
        Dog_GetWeight(&d),
        Dog_GetLegs(&d));
    //多态:描述一种动态行为,在C++中,只有通过基类引用或者指针,
    //去调用虚函数的时候才发生多态,C++内部通过一个虚表实现多态
    //如果一门语言只支持类,打不支持多态,只能说它是基于对象的,而不是面向对象的
    Dog dd;
    Dog_Ctor(&dd, 2, 2, 4);
    //把子类对象赋值给父类指针
    Animal* pa = &dd;
    //传递父类指针,将会调用子类中实现的虚函数
    Animal_Say(pa);
    return 0;
}

相关文章

  • (十九)面向对象编程

    无论C语言或是C++,Java,甚至脚本语言,汇编语言都能实现面向对象编程 面向对象设计过程 假设存在一个对象。要...

  • iOS Runtime

    Runtime背景 OC是基于C的一门面向对象的语言,C语言是一门面向过程的语言,面向对象的实现是通过C语言的一套...

  • (七)go语言面向对象

    面向对象 简介 go 语言中没有对象,和c语言类似,通过struct实现面向对象的程序编写,如下图:TreeNod...

  • 好好干

    C语言面向过程 C++面向对象

  • 重学iOS——1.从C角度看OC

    面向对象 面向对象的编程思维,简而言之就是:一切皆对象。面向对象的语言区别于C语言(面向过程),C语言是按照代码的...

  • 面向对象的基本概念

    面向对象的基本概念 1. 简述 C 和 C++ 有何不同? 宏观上: C 语言属于面向过程语言,通过函数来实现程序...

  • 3. Java面向对象编程

    类与对象[1] Java是面向对象的汇编语言(面向机器)—— c语言(面向过程)—— java语言(面向对象) 类...

  • Objective-C 语言特性之深入理解对象

    Objective-C 语言是一门面向对象的语言,Objectvie-C语言的底层是由c/c++和部分汇编语言实现...

  • 关于“C++面向对象高级编程上”第一次作业

    c语言面向过程,c++(以前为c with class)面向对象 面对对象的语言还有Java,C# 教学目的:良好...

  • 【Boolan】C++面向对象编程(上)-Clarence

    c语言面向过程,c++(以前为c with class)面向对象 面对对象的语言还有Java,C# 教学目的:良好...

网友评论

      本文标题:C语言实现面向对象

      本文链接:https://www.haomeiwen.com/subject/ychoddtx.html