精华内容
下载资源
问答
  • C语言实现面向对象

    千次阅读 2018-05-10 08:57:46
    from : ...C语言不是面向对象语言却也可以用来实现面向对象思想的。有人会觉得用C实现面向对象,充其量是模拟面向对象的语法,而不是像C++那样真的面向对象的。这也算是不太...

    from : https://blog.csdn.net/vic_chang/article/details/8457800

    C语言是面向过程的语言,可以用来实现面向对象么?答案是肯定的。

    面向对象的本质是一种设计思想,与具体的语言没有多大的关系。C语言不是面向对象语言却也可以用来实现面向对象思想的。
    有人会觉得用C实现面向对象,充其量是模拟面向对象的语法,而不是像C++那样真的面向对象的。这也算是不太正确的看法的。
    为什么这么说?
    请先看看C++的类与对象吧
    class student
    {
      public:
         Int getNum() 
         {
    }
      private:
         Int num;
    };
    这是一个基本的C++类的声明,当使用这个类定义一个东西的时候,如:
    student one;
    编译器也就为one 这个对象只为数据成员分配了空间,即为 int num; 分配了空间,
    没有为所谓 getNum()方法来分配任何东西的。
    如果用C来写,就可以这样写:
    struct student
    {
       Int num;
    };
     Int getNum()
    {
    }
    用C写的这段code与C++写的那段code本质是等效的。
    不过,有人要说了,C++声明的student类会有构造函数及析构函数,你的C语言就没有。。
    OK,我们先给上述C++的code加上一个构造函数。
    class student
    {
      public:
        student(int number=0){num = number;}
      private:
        Int num;
    };
    在定义一个student one(1);时, 构造函数就会被调用。
    构造函数是怎么被调用的呢??我们好象看不到调用呢??
    我们之所以看不到,其实是因为编译器在生成代码的时候,已经在定义后面加入了调用的代码了,这个过程程序员没有参与。也就是等效于:
     student one; //定义一个对象
     student(1); //调用构造函数,由编译器加入的代码。

    好了,明白这点,那么,我们的C语言也可以写构造函数了。
    struct student
    {
       Int num;
    };

    void student(int number, struct student * p)
    {
       p->num = number;
    }

    struct student one;   //定义一个结构体对象
    student(1, &one);   //构造函数

    写到现在,用C语言实现面向对象主要有以下几点:
    1. 在内存分配上,struct 类型与class类型数据是一样的,都只是存储数据的。类的成员函数跟普通函数是一样编译存储的。它所以能跟类关联在一起,实际是由编译器在保证的。用C语言来写的时候,这个关联性由程序员来控制。

    2. 对象的构造函数与析构函数的调用,其实是由编译器在做调用。编译器在生成最终的二进制代码的时候,加入了它们的调用代码。类的其他特性也是如此。

    3.  类的访问控制private, public, protected这些特性都是由编译器来保证的。最终生成的代码没有这些属性的。
    4. 用C实现面向对象,其实就是把C++中编译器把所做的部分工作,转为由程序员来做。这样造成的结果无非就是程序员多写一点代码而已。在编译生成的最终汇编代码中,C所实现的面向对象是可以与C++的面向对象保持一致的code.

    展开全文
  • 【C语言】C语言实现面向对象编程之封装代码.,完整的代码,可以在Linux和VS环境运行。【C语言】C语言实现面向对象编程之封装代码.rar
  • 附件是在VS2012下用C语言实现面向对象的示例代码,并实现设计模式中的工厂模式
  • C语言 实现面向对象

    2018-08-03 11:22:10
    /*对象的功能实现*/ int open_file(char *path,int flag,unsigned int mode) { int fd = 0; return open(path,flag,mode); } /*对象的功能实现*/ int write_file(int fd,char *buf,int size) { return write(fd,...

     

    /*************************************************************************
        > File Name: object.c
        > Author: TANG
        > Mail: tjcmail@126.com 
        > Created Time: 2018年08月03日 星期五 10时32分33秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    
    /*对象的功能描述*/
    typedef struct{
    	int fd;
    	int (*open)(char *path,int flag,unsigned int mode);
    	int (*write)(int fd,char *buf,int size);
    	void (*close)(int fd);
    }file_t;
    
    /*对象的功能实现*/
    int open_file(char *path,int flag,unsigned int mode)
    {	
    	int fd = 0;
    	return open(path,flag,mode);
    }
    /*对象的功能实现*/
    int write_file(int fd,char *buf,int size)
    {
    	return write(fd,buf,size);
    }
    /*对象的功能实现*/
    void close_file(int fd)
    {
    	close(fd);
    }
    
    
    int main()
    {
    	char *str = "hello! My object!\n";
    
    	/*创造一个对象*/
    	file_t tfile;
    
    	/*给对象初始化一下*/
    	tfile.open = open_file;
    	tfile.write = write_file;
    	tfile.close = close_file;
    	
    	/*就可以用了*/
    	tfile.fd = tfile.open("hello.txt",O_CREAT|O_RDWR,0664);
    	tfile.write(tfile.fd,str,strlen(str));
    	tfile.close(tfile.fd);
    
    	return 0;
    }

     

    展开全文
  • c语言实现面向对象OOP

    2012-04-01 08:45:10
    c语言实现面向对象OOP
  • c语言实现面向对象

    2008-11-16 11:40:04
    c语言实现面向对象c语言实现面向对象
  • 所以在正式开始设计模式前,先看看如何用C语言实现面向对象编程。 本章针对面向对象的封装、继承、组合、多态给出C语言的实现方法。 1 封装 封装是指对象仅暴露必要的对外接口(这里指public方法)来和其它

    GOF的《设计模式》一书的副标题叫做“可复用面向对象软件的基础”,从标题就能看出面向对象是设计模式基本思想。由于C语言并不是面向对象的语言,C语言没有直接提供封装、继承、组合、多态等面向对象的功能,但C语言有struct和函数指针。我们可以用struct中的数据和函数指针,以此来模拟对象和类的行为。

    所以在正式开始设计模式前,先看看如何用C语言实现面向对象编程。

    本章针对面向对象的封装、继承、组合、多态给出C语言的实现方法。

    1 封装
    封装是指对象仅暴露必要的对外接口(这里指public方法)来和其它对象进行交互,其它的属性和行为都无需暴露,这使得对象的内部实现可以自由修改。这也要求对象包含它能进行操作所需要的所有信息,不必依赖其它对象来完成自己的操作。

    以下以电力公司的例子演示封装。

    电力公司生产并提供电力。为了汇聚各种发电厂的电力并让用户获得电力,电力公司提供了两个统一接口:1、电力公司汇聚各种发电厂的电力,无论是火力发电厂、水力发电厂、原子能发电厂等都使用一个接口。如果什么时候一家火力发电厂改造成了风力发电厂,发电厂的实现完全不一样了,但接口不变,所以电力公司感觉不到发电厂变了,不需要为了发电厂实现升级而改造电力公司的系统。2、电力公司向用户提供电力,无论用户用电的设备是烤面包机还是洗衣机,电力公司和用户之间都使用一个接口(电源插座)。用户的用电设备可以千变万化,但接口(电源插座)不变。所以电力公司不用关系用户的什么设备在用电。

    代码

    #include <stdio.h>
    
    struct PowerCompany {
        int powerReserve;
        void (*PowerPlant)(struct PowerCompany *ths, int power);
        void (*PowerUser)(struct PowerCompany *ths, int power);
    };
    
    
    void PowerPlant(struct PowerCompany *ths, int power)
    { 
        ths->powerReserve += power;
        printf("发电%d瓦\n", power); 
        return;  
    }
    
    void PowerUser(struct PowerCompany *ths, int power)
    {
        if (ths->powerReserve >= power) {
            printf("用电%d瓦\n", power);
            ths->powerReserve -= power;
        } else {
            printf("电力不足\n");
        }
        return;
    }
    
    /* struct PowerCompany 的构造函数 */
    void InitPowerCompany(struct PowerCompany *ths)
    {
        ths->powerReserve = 0;
        ths->PowerPlant = PowerPlant;
        ths->PowerUser = PowerUser;
        return;
    }
    
    /* struct PowerCompany 的析构函数 */
    void DeInitPowerCompany(struct PowerCompany *ths)
    {
    
    }
    
    main()
    {
        struct PowerCompany mPowerComp;
        InitPowerCompany(&mPowerComp);
    
        /* 发电 */
        mPowerComp.PowerPlant(&mPowerComp, 200);
        mPowerComp.PowerPlant(&mPowerComp, 3000);
    
        /* 用电 */
        mPowerComp.PowerUser(&mPowerComp, 100);
        mPowerComp.PowerUser(&mPowerComp, 6000);
        
        DeInitPowerCompany(&myPowerCompany);
        return;
    }


    从电力公司的例子中可以看出,良好的封装可以有效减少耦合性,封装内部实现可以自由修改,对系统的其它部分没有影响。

    2 继承
    面向对象编程最强大的功能之一就是代码重用,而继承就是实现代码重用的主要手段之一。
    继承允许一个类继承另一个类的属性和方法。我们可以通过识别事物之间的共性,通过抽象公共属性和行为来构造父类,而通过继承父类来构造各子类。父类,即公共属性和行为,就得到了复用。

    以下哺乳动物的例子演示继承。

    猫和狗都是哺乳动物,它们具有公共的属性和行为。比如,猫和狗都有眼睛,且它们都会叫。我们把眼睛的颜色、会叫抽象出来,作为哺乳动物父类的属性,让猫类、狗类都继承哺乳动物父类,可实现对”眼睛的颜色“、”会叫“实现的复用。

    UML


    代码

    #include <stdio.h>
    
    struct Animal {
        int eyeColor;
        void (*ShowEyeColor)(struct Animal *ths);
        int callNum;
        void (*Call)(struct Animal *ths);
    };
    
    void ShowEyeColor(struct Animal *ths)
    {
        if (ths->eyeColor == 1) {
            printf("眼睛是绿色\n");
        } else {    
            printf("眼睛是蓝色\n");
        }
        return;
    }
    
    void Call(struct Animal *ths)
    {
        printf("叫%d声\n", ths->callNum);
        return;
    }
    
    // struct Animal 的构造函数
    void Animal(struct Animal *ths, int eyeColor, int callNum)
    {
        ths->eyeColor = eyeColor;    
        ths->ShowEyeColor = ShowEyeColor;  
        ths->callNum = callNum;
        ths->Call = Call;
        return;  
    }
    
    struct Dog {
        struct Animal animal;
    };
    
    // struct Dog 的构造函数
    void Dog(struct Dog *ths, int eyeColor, int callNum)
    {
        Animal(ths, eyeColor, callNum);
        // 狗类的其它属性,略
        return;
    }
    
    // struct Dog 的析构函数
    void  _Dog(struct Dog *ths)
    {
    
    }
    
    struct Cat {
        struct Animal animal;
        // 猫类的其它属性,略
    };
    
    // struct Cat 的构造函数
    void Cat(struct Cat *ths, int eyeColor, int callNum)
    {
        Animal(ths, eyeColor, callNum);
        return;
    }
    
    // struct Cat 的析构函数
    void  _Cat(struct Cat *ths)
    {
    
    }
    
    main()
    {
        struct Dog mDog;
        Dog(&mDog, 1, 3);
        myDog.animal.ShowEyeColor(&mDog);
        myDog.animal.Call(&mDog);
        _Dog(&mDog);
     
        struct Cat mCat;
        Cat(&mCat, 2, 5);
        myCat.animal.ShowEyeColor(&mCat);
        myCat.animal.Call(&mCat);
        _Cat(&mCat); 
        
        return;
    }


    3 多态
    多态与继承是紧耦合的关系,但它通常作为面向对象技术中最强大的优点之一。子类从继承父类的接口,每个子类是单独的实体,每个子类需要对同一消息有单独的应答。每个子类对同一消息的应答采用继承的相同接口,但每个子类可以有不同的实现,这就是多态。

    在猫和狗的例子中,猫类、狗类都继承了哺乳动物父类的“叫”的方法,但猫类、狗类的叫声并不一样,所以猫类、狗类可以采用不同的“叫”的实现。

    以下代码演示了多态。

    代码

    #include <stdio.h>
    
    struct Animal {
        int eyeColor;
        void (*ShowEyeColor)(struct Animal *this);
        int callNum;
        void (*Call)(struct Animal *this);
    };
    
    void ShowEyeColor(struct Animal *this)
    {
        if (this->eyeColor == 1) {
            printf("眼睛是绿色\n");
        } else {    
            printf("眼睛是蓝色\n");
        }
        return;
    }
    
    void Call(struct Animal *this)
    {
        printf("叫%d声\n", this->callNum);
        return;
    }
    
    /* struct Animal 的构造函数 */
    void Animal(struct Animal *this, int eyeColor, int callNum)
    {
        this->eyeColor = eyeColor;    
        this->ShowEyeColor = ShowEyeColor;  
        this->callNum = callNum;
        this->Call = Call;
        return;  
    }
    
    struct Dog {
        struct Animal animal;
    };
    
    void Bark(struct Dog *this)
    {
        int i;
        for (i = 0; i < this->animal.callNum; i++) {
            printf("汪 ");
        }
        printf("\n");
        return;
    }
    
    /* struct Dog 的构造函数 */
    void Dog(struct Dog *this, int eyeColor, int callNum)
    {
        Animal(this, eyeColor, callNum);
        this->animal.Call = Bark;
        return;
    }
    
    // struct Dog 的析构函数
    void  _Dog(struct Dog *this)
    {
    
    }
    
    struct Cat {
        struct Animal animal;
    };
    
    void Meow(struct Cat *this)
    {
        int i;
        for (i = 0; i < this->animal.callNum; i++) {
            printf("喵 ");
        }
        printf("\n");
        return;
    }
    
    /* struct Cat 的构造函数 */
    void Cat(struct Cat *this, int eyeColor, int callNum)
    {
        Animal(this, eyeColor, callNum);
        this->animal.Call = Meow;
        return;
    }
    
    // struct Cat 的析构函数
    void  _Cat(struct Cat *this)
    {
    
    }
    
    main()
    {
        struct Dog myDog;
        Dog(&myDog, 1, 3);
        
        struct Cat myCat;
        Cat(&myCat, 2, 5);
    
        struct Animal *manimal;
        myAnimal = &myDog;
        myAnimal->Call(manimal);
        myAnimal = &myCat;
        myAnimal->Call(manimal);
    
        _Dog(&myDog);
        _Cat(&myCat);
    
        return;
    }


    4 组合
    组合与继承都是面向对象中代码复用的方式,也只有通过组合和继承两种方式能够实现使用其他类构建新类。

    在前面讲的继承关系中,我们把通用属性和行为抽象出来作为父类。例如:猫、狗都是哺乳动物,它们具有哺乳动物通用的属性和行为。猫、狗与哺乳动物的关系是“is-a”,即猫、狗(is-a)哺乳动物。
    而组合关系体现的是“has-a”。以房子和窗户的关系举例。我们可以单独构建窗户类,然后把窗户类应用到各种房子类上。此时房子(has-a)窗户,但绝不是窗户(is-a)房子。

    以下UML和代码演示了组合。

    UML

    代码

    #include <stdio.h>
    
    struct Window {
        int length;
        int width;
        void (*ShowWindow)(struct Window *this);
    };
    
    void ShowWindow(struct Window *this)
    {
        printf("这是长%d厘米、宽%d厘米的窗户\n", this->length, this->width);
        return;
    }
    
    void Window(struct Window *this, int length, int width)
    {
        this->length = length;
        this->width = width;
        this->ShowWindow = ShowWindow;
        return;
    }
    
    void _Window(struct Window *this)
    {
    
    }
    
    struct House {
        struct Window *window;
        int livingRoomNum;
        int bedRoomNum;
        int bathRoomNum;
        void (*ShowHouse)(struct House *this);
    };
    
    void ShowHouse(struct House *this)
    {
        printf("这是%d室%d厅%d卫的房子\n", this->bedRoomNum, this->livingRoomNum, this->bathRoomNum);
        return;
    }
    
    
    void House(struct House *this, int livingRoomNum, int bedRoomNum, int bathRoomNum)
    {
        this->livingRoomNum = livingRoomNum;
        this->bedRoomNum = bedRoomNum;
        this->bathRoomNum = bathRoomNum;
        this->ShowHouse = ShowHouse;
        return;
    }
    
    void _House(struct House *this)
    {
    
    }
    
    void main()
    {
        struct House myHouse;
        House(&myHouse, 2, 3, 2);
        
        /* 组合是一种低耦合,如果不初始化,子类只是存放了一个空指针来占位关联。
           此处是与继承关系的区别。继承是一种强耦合,在继承关系中,无论如何子类拥有父类全部的信息。*/
        struct Window myWindow1;
        myHouse.window = &myWindow1;
        Window(myHouse.window, 100, 50);
    
        /* 通过获得其它对象的引用而在“运行时”动态定义 */
        myHouse.ShowHouse(&myHouse);
        myHouse.window->ShowWindow(myHouse.window);
    
        _Window();
        _House();
    
        return;
    }


    组合和继承的区别有以下几点:

    组合关系体现的是“has-a”。继承关系体现的是“is-a”。

    展开全文
  • 1 用C语言实现面向对象编程 GOF的《设计模式》一书的副标题叫做“可复用面向对象软件的基础”,从标题就能看出面向对象是设计模式基本思想。由于C语言并不是面向对象的语言,C语言没有直接提供封装、继承、组合、...

    用C语言实现面向对象编程

    GOF的《设计模式》一书的副标题叫做“可复用面向对象软件的基础”,从标题就能看出面向对象是设计模式基本思想。由于C语言并不是面向对象的语言,C语言没有直接提供封装、继承、组合、多态等面向对象的功能,但C语言有struct和函数指针。我们可以用struct中的数据和函数指针,以此来模拟对象和类的行为。

    所以在正式开始设计模式前,先看看如何用C语言实现面向对象编程。

    本章针对面向对象的封装、继承、组合、多态给出C语言的实现方法。

    1 封装

    封装是指对象仅暴露必要的对外接口(这里指public方法)来和其它对象进行交互,其它的属性和行为都无需暴露,这使得对象的内部实现可以自由修改。这也要求对象包含它能进行操作所需要的所有信息,不必依赖其它对象来完成自己的操作。

    以下以电力公司的例子演示封装。

    电力公司生产并提供电力。为了汇聚各种发电厂的电力并让用户获得电力,电力公司提供了两个统一接口:1、电力公司汇聚各种发电厂的电力,无论是火力发电厂、水力发电厂、原子能发电厂等都使用一个接口。如果什么时候一家火力发电厂改造成了风力发电厂,发电厂的实现完全不一样了,但接口不变,所以电力公司感觉不到发电厂变了,不需要为了发电厂实现升级而改造电力公司的系统。2、电力公司向用户提供电力,无论用户用电的设备是烤面包机还是洗衣机,电力公司和用户之间都使用一个接口(电源插座)。用户的用电设备可以千变万化,但接口(电源插座)不变。所以电力公司不用关系用户的什么设备在用电。

    代码

    #include <stdio.h>
    
    struct PowerCompany {
        int powerReserve;
        void (*PowerPlant)(struct PowerCompany *this, int power);
        void (*PowerUser)(struct PowerCompany *this, int power);
    };
    
    
    void PowerPlant(struct PowerCompany *this, int power)
    { 
        this->powerReserve += power;
        printf("默认发电厂,发电%d瓦\n", power); 
        return;  
    }
    
    void PowerUser(struct PowerCompany *this, int power)
    {
        if (this->powerReserve >= power) {
            printf("用电%d瓦\n", power);
            this->powerReserve -= power;
        } else {
            printf("电力不足,用电失败\n");
        }
        return;
    }
    
    /* struct PowerCompany 的构造函数 */
    void PowerCompany(struct PowerCompany *this)
    {
        this->powerReserve = 0;
        this->PowerPlant = PowerPlant;
        this->PowerUser = PowerUser;
        return;
    }
    
    /* struct PowerCompany 的析构函数 */
    void _PowerCompany(struct PowerCompany *this)
    {
    
    }
    
    main()
    {
        struct PowerCompany myPowerCompany;
        PowerCompany(&myPowerCompany);
    
        /* 发电 */
        myPowerCompany.PowerPlant(&myPowerCompany, 1000);
    
        /* 用电 */
        myPowerCompany.PowerUser(&myPowerCompany, 800);
        myPowerCompany.PowerUser(&myPowerCompany, 800);
        
        _PowerCompany(&myPowerCompany);
        return;
    }
    

    从电力公司的例子中可以看出,良好的封装可以有效减少耦合性,封装内部实现可以自由修改,对系统的其它部分没有影响。

    2 继承

    面向对象编程最强大的功能之一就是代码重用,而继承就是实现代码重用的主要手段之一。
    继承允许一个类继承另一个类的属性和方法。我们可以通过识别事物之间的共性,通过抽象公共属性和行为来构造父类,而通过继承父类来构造各子类。父类,即公共属性和行为,就得到了复用。

    以下哺乳动物的例子演示继承。

    猫和狗都是哺乳动物,它们具有公共的属性和行为。比如,猫和狗都有眼睛,且它们都会叫。我们把眼睛的颜色、会叫抽象出来,作为哺乳动物父类的属性,让猫类、狗类都继承哺乳动物父类,可实现对”眼睛的颜色“、”会叫“实现的复用。

    UML
    在这里插入图片描述

    代码

    #include <stdio.h>
    
    struct Mammal {
        int eyeColor;
        void (*ShowEyeColor)(struct Mammal *this);
        int callNum;
        void (*Call)(struct Mammal *this);
    };
    
    void ShowEyeColor(struct Mammal *this)
    {
        if (this->eyeColor == 1) {
            printf("眼睛是绿色\n");
        } else {    
            printf("眼睛是蓝色\n");
        }
        return;
    }
    
    void Call(struct Mammal *this)
    {
        printf("叫%d声\n", this->callNum);
        return;
    }
    
    // struct Mammal 的构造函数
    void Mammal(struct Mammal *this, int eyeColor, int callNum)
    {
        this->eyeColor = eyeColor;    
        this->ShowEyeColor = ShowEyeColor;  
        this->callNum = callNum;
        this->Call = Call;
        return;  
    }
    
    struct Dog {
        struct Mammal mammal;
    };
    
    // struct Dog 的构造函数
    void Dog(struct Dog *this, int eyeColor, int callNum)
    {
        Mammal(this, eyeColor, callNum);
        // 狗类的其它属性,略
        return;
    }
    
    // struct Dog 的析构函数
    void  _Dog(struct Dog *this)
    {
    
    }
    
    struct Cat {
        struct Mammal mammal;
        // 猫类的其它属性,略
    };
    
    // struct Cat 的构造函数
    void Cat(struct Cat *this, int eyeColor, int callNum)
    {
        Mammal(this, eyeColor, callNum);
        return;
    }
    
    // struct Cat 的析构函数
    void  _Cat(struct Cat *this)
    {
    
    }
    
    main()
    {
        struct Dog myDog;
        Dog(&myDog, 1, 3);
        myDog.mammal.ShowEyeColor(&myDog);
        myDog.mammal.Call(&myDog);
        _Dog(&myDog);
     
        struct Cat myCat;
        Cat(&myCat, 2, 5);
        myCat.mammal.ShowEyeColor(&myCat);
        myCat.mammal.Call(&myCat);
        _Cat(&myCat); 
        
        return;
    }
    

    3 多态

    多态与继承是紧耦合的关系,但它通常作为面向对象技术中最强大的优点之一。子类从继承父类的接口,每个子类是单独的实体,每个子类需要对同一消息有单独的应答。每个子类对同一消息的应答采用继承的相同接口,但每个子类可以有不同的实现,这就是多态。

    在猫和狗的例子中,猫类、狗类都继承了哺乳动物父类的“叫”的方法,但猫类、狗类的叫声并不一样,所以猫类、狗类可以采用不同的“叫”的实现。

    以下代码演示了多态。

    代码

    #include <stdio.h>
    
    struct Mammal {
        int eyeColor;
        void (*ShowEyeColor)(struct Mammal *this);
        int callNum;
        void (*Call)(struct Mammal *this);
    };
    
    void ShowEyeColor(struct Mammal *this)
    {
        if (this->eyeColor == 1) {
            printf("眼睛是绿色\n");
        } else {    
            printf("眼睛是蓝色\n");
        }
        return;
    }
    
    void Call(struct Mammal *this)
    {
        printf("叫%d声\n", this->callNum);
        return;
    }
    
    /* struct Mammal 的构造函数 */
    void Mammal(struct Mammal *this, int eyeColor, int callNum)
    {
        this->eyeColor = eyeColor;    
        this->ShowEyeColor = ShowEyeColor;  
        this->callNum = callNum;
        this->Call = Call;
        return;  
    }
    
    struct Dog {
        struct Mammal mammal;
    };
    
    void Bark(struct Dog *this)
    {
        int i;
        for (i = 0; i < this->mammal.callNum; i++) {
            printf("汪 ");
        }
        printf("\n");
        return;
    }
    
    /* struct Dog 的构造函数 */
    void Dog(struct Dog *this, int eyeColor, int callNum)
    {
        Mammal(this, eyeColor, callNum);
        this->mammal.Call = Bark;
        return;
    }
    
    // struct Dog 的析构函数
    void  _Dog(struct Dog *this)
    {
    
    }
    
    struct Cat {
        struct Mammal mammal;
    };
    
    void Meow(struct Cat *this)
    {
        int i;
        for (i = 0; i < this->mammal.callNum; i++) {
            printf("喵 ");
        }
        printf("\n");
        return;
    }
    
    /* struct Cat 的构造函数 */
    void Cat(struct Cat *this, int eyeColor, int callNum)
    {
        Mammal(this, eyeColor, callNum);
        this->mammal.Call = Meow;
        return;
    }
    
    // struct Cat 的析构函数
    void  _Cat(struct Cat *this)
    {
    
    }
    
    main()
    {
        struct Dog myDog;
        Dog(&myDog, 1, 3);
        
        struct Cat myCat;
        Cat(&myCat, 2, 5);
    
        struct Mammal *myMammal;
        myMammal = &myDog;
        myMammal->Call(myMammal);
        myMammal = &myCat;
        myMammal->Call(myMammal);
    
        _Dog(&myDog);
        _Cat(&myCat);
    
        return;
    }
    

    4 组合

    组合与继承都是面向对象中代码复用的方式,也只有通过组合和继承两种方式能够实现使用其他类构建新类。

    在前面讲的继承关系中,我们把通用属性和行为抽象出来作为父类。例如:猫、狗都是哺乳动物,它们具有哺乳动物通用的属性和行为。猫、狗与哺乳动物的关系是“is-a”,即猫、狗(is-a)哺乳动物。
    而组合关系体现的是“has-a”。以房子和窗户的关系举例。我们可以单独构建窗户类,然后把窗户类应用到各种房子类上。此时房子(has-a)窗户,但绝不是窗户(is-a)房子。

    以下UML和代码演示了组合。

    UML

    在这里插入图片描述

    代码

    #include <stdio.h>
    
    struct Window {
        int length;
        int width;
        void (*ShowWindow)(struct Window *this);
    };
    
    void ShowWindow(struct Window *this)
    {
        printf("这是长%d厘米、宽%d厘米的窗户\n", this->length, this->width);
        return;
    }
    
    void Window(struct Window *this, int length, int width)
    {
        this->length = length;
        this->width = width;
        this->ShowWindow = ShowWindow;
        return;
    }
    
    void _Window(struct Window *this)
    {
    
    }
    
    struct House {
        struct Window *window;
        int livingRoomNum;
        int bedRoomNum;
        int bathRoomNum;
        void (*ShowHouse)(struct House *this);
    };
    
    void ShowHouse(struct House *this)
    {
        printf("这是%d室%d厅%d卫的房子\n", this->bedRoomNum, this->livingRoomNum, this->bathRoomNum);
        return;
    }
    
    
    void House(struct House *this, int livingRoomNum, int bedRoomNum, int bathRoomNum)
    {
        this->livingRoomNum = livingRoomNum;
        this->bedRoomNum = bedRoomNum;
        this->bathRoomNum = bathRoomNum;
        this->ShowHouse = ShowHouse;
        return;
    }
    
    void _House(struct House *this)
    {
    
    }
    
    void main()
    {
        struct House myHouse;
        House(&myHouse, 2, 3, 2);
        
        /* 组合是一种低耦合,如果不初始化,子类只是存放了一个空指针来占位关联。
           此处是与继承关系的区别。继承是一种强耦合,在继承关系中,无论如何子类拥有父类全部的信息。*/
        struct Window myWindow1;
        myHouse.window = &myWindow1;
        Window(myHouse.window, 100, 50);
    
        /* 通过获得其它对象的引用而在“运行时”动态定义 */
        myHouse.ShowHouse(&myHouse);
        myHouse.window->ShowWindow(myHouse.window);
    
        _Window();
        _House();
    
        return;
    }
    

    组合和继承的区别有以下几点:

    组合关系体现的是“has-a”。继承关系体现的是“is-a”。

    组合是“黑箱”复用,通过获得其它对象的引用而在“运行时”动态定义。继承是“白箱”复用,“编译时”静态定义。

    这点非常非常的重要,后续讲到具体设计模式时,经常会使用“运行时”动态定义替代“编译时”静态定义方式来实现

    展开全文
  • c语言实现面向对象

    2012-01-04 20:55:32
    //cobj.h #ifndef _COBJ_ #define _COBJ_ typedef void* HPERSON;...HPERSON createPserson...对象,在程序的接口中每一个对象至少需要有建立 删除 两个基本函数,然后根据需要实现其他的操作函数。  
  • C语言实现面向对象的方法,面向对象的三个基本特征,对象唯一性,继承性,抽象性。 使用C语言中的结构体和函数指针将数据与操作放在一起,使得一个问题的解决方法封装在结构体中。 其中结构体的嵌套使用实现了...
  • 以下代码是我用纯C语言实现面向对象的一种方式。C语言实现面向对象从应用级开发来讲,纯粹是个鸡肋,所以勿喷!这里只是提供一个思考问题的方向而已! 先来一个父类的头文件 Father.h #ifndef _FATHER_H_ #define...
  • 我们有C++面向对象的语言,为什么还要用C语言实现面向对象呢? C语言这种非面向对象的语言,同样也可以使用面向对象的思路来编写程序的。只是用面向对象的C++语言来实现面向对象编程会更简单一些,但是C语言的高效性...
  • C语言实现面向对象的方法,面向对象的三个基本特征,对象唯一性,继承性,抽象性。 使用C语言中的结构体和函数指针将数据与操作放在一起,使得一个问题的解决方法封装在结构体中。 其中结构体的嵌套使用实现了...
  • pdf文件,用C语言实现面向对象编程英文版
  • 最近百度面试过程中有同学被问到这样一个问题:如何用C语言实现面向对象?我们都知道面向对象的三大基本特征:封装、继承和多态,C++语言和编译器都对这些特征有着强有力的支持,但是对于C这样的函数式语言,如何...
  • C语言实现面向对象,听起来就有不可思议的感觉,那真的可以实现吗?我觉得OK! 要使用C语言这种面向过程的语言来实现面向对象,首先要做的事情是去了解面向对象是怎样的概念,列:继承的本质是怎样的一回事,多态...
  • 使用C语言实现面向对象的设计 一 http://blog.sina.com.cn/s/blog_54533619010000bk.html 使用C语言实现面向对象的设计 二   http://blog.sina.com.cn/s/blog_54533619010000bl.html ...
  • 面试官:C和C++有什么...可能很少有人想过用C语言实现面向对象编程(真的麻烦,感觉就是吃力不讨好),但是,通过这样的尝试,可以使我们的学习过程更有意思。也能通过用C语言实现面向对象编程来深化对封装、继承、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,496
精华内容 1,398
关键字:

c语言实现面向对象

c语言 订阅