【探索】- (类的本质)尝试用C实现一个OC类

目录

概述

类的本质也是一个对象,是Class类的实例,简称“类对象”。
那么,Class类的本质又是什么呢?

探索

1#
官方给出的Class类型的定义是这样的:

typedef struct objc_class *Class

从这里我们可以看出,Class这个类的本质是一个名叫objc_class的结构体。

2#
我们知道,一个典型的类中包含两部分内容:成员变量、方法,不难推测出,结构体中应该也包含这两部分内容:
1. 由指向基本数据类型或其他结构体的指针构成的成员变量区
2. 由指向函数的指针所构成的方法区

尝试

OK,猜想完毕后,我们来尝试做一个拥有类的基本功能的结构体。
PS.类的基本功能:
1. 创建对象
2. 使用自定义的其他方法
当然这仅仅是最浅层次的模拟,不涉及到其他特性。

需求

创建一个Car结构体,要求实现:
1. 拥有speed属性
2. 提供一个new函数,以该结构体为模板创建新结构体
3. 新结构体不能使用new函数
4. 新结构体可以使用run函数,并在屏幕上输出“车子跑起来了”

代码

经过一段时间的探索之后,得到了如下代码,可以满足上述需求。

//
//  main.m
//  类的本质探索
//
//  Created by Azen.Xu on 15/3/14.
//  Copyright (c) 2015年 Azen.Xu. All rights reserved.
//

/* 
 创建一个Car结构体,要求实现:
 1. 拥有speed属性
 2. 提供一个new函数,以该结构体为模板创建新结构体
 3. 新结构体不能使用new函数
 4. 新结构体可以使用run函数,并在屏幕上输出“车子跑起来了”
 */
#import <Foundation/Foundation.h>
//  函数声明
void run();
struct CarB new();  //此例说明,结构体未定义以前,也可以声明返回值为结构体的函数


//  定义结构体
//  CarB结构体用来存放对象方法指针;
struct CarB{
    int _speed;
    void (*run)();
};

//  Car结构体用来存放类方法指针
struct Car{
    struct CarB (*new)();
}Car = {new};                 //在定义结构体的同时赋初值是因为,结构体必须在定义之后才会分配内存,才能调用方法。

//  主程序入口
int main()
{
//    调用Car“类”的new方法生成两个newCar“对象”
    struct CarB newCarA = Car.new();
    struct CarB newCarB = Car.new();
//    设置newCar的_speed“实例变量”值为100
    newCarA._speed = 100;
    newCarB._speed = 20;
    printf("A的速度是%d,B的速度是%d\n",newCarA._speed,newCarB._speed);
//    测试run方法
    newCarA.run();


    return 0;
}


//  函数实现
//  new方法
struct CarB new()
{
    struct CarB newCar = {0,run};  // 此处一定要记得赋初值
    return newCar;
}
//  run方法
void run()
{
    printf("车子跑起来了\n");
}

总结

思路总结

通过这个例子,我们知道,采用结构体的方法可以实现与OC类相同的效果。
而一个OC类需要两个结构体来实现:
1. 结构体1用来存放类方法,其成员仅有“类方法”函数指针,且需要在声明结构体的同时定义好结构体变量(这样才能使类方法函数指针指向正确的函数)
2. 结构体2用来存放成员变量及对象方法
3. +new方法中,应当对生成的结构体初始化后(对象方法指针指向正确的函数)再返回

C方法总结

通过这个例子,对C语言知识进行了有效的复习:

结构体

1. 成员运算符“.”
2. 结构体的声明、实现、初始化(定义及实例)
//#1
//标准声明方式
struct 结构体名{
  成员变量列表;
};
//标准实现方式
struct 结构体名 结构体变量名 = {初始化值,初始化值,...};
//#2
//声明同时实现并初始化
struct 结构体名{
  成员变量列表;
}结构体变量名 = {初始化值,初始化值,...}
//#3
//匿名实现并初始化
struct{
  成员变量列表;
}结构体变量名 = {初始化值,初始化值,...}
//#4
//typedef的应用
//声明
typedef struct 结构体名{
  成员变量列表;
}结构体别名;
//实现
结构体别名 变量名 = {值值值,...}
3. 结构体成员值的修改
//#1箭头
结构体变量名->成员名 = 值;
//#2成员运算符
结构体变量名.成员名 = 值;

指向函数的指针

1. 定义

返回值名 (*指针名)(参数列表);

2. 指函数

指针名 = 函数名;

3. 使用

指针名();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值