参考资料:

     http://blog.chinaunix.net/uid-26750235-id-3102371.html

     http://www.eventhelix.com/realtimemantra/basics/ComparingCPPAndCPerformance2.htm#.U0jCR7KBR7h

 

说明:

         Shape类为基类,包含typeName,虚函数为求解Shape的周长、面积、析构函数

 

头文件 Cobject.h

#pragma once

/*
*    使用C实现面向对象编程:封装、继承、多态
*/

//基类
struct Shape
{
    char *typeName;
    struct ShapeOps *ops;
};

//基类虚函数指针
struct ShapeOps
{
    float (*OpsArea)(struct Shape* shape);    //求面积
    int (*OpsPerimeter)(struct Shape* shape);    //求周长
    void (*OpsDestory)(struct Shape *shape);    //析构对象
};

//基类的虚函数
float Area(struct Shape *shape);
int Perimeter(struct Shape *shape);
void Destory(struct Shape *shape);

/*********************************************************************************/

//派生类“三角形”triangle
struct Triangle
{
    struct Shape shape;
    int a;
    int b;
    int c;
};

//派生类接口
struct Triangle* TriCreate(int a,int b,int c);
float TriArea(struct Shape *triangle);
int TriPerimeter(struct Shape *triangle);
void TriDestory(struct Shape *triangle);

extern struct ShapeOps TriangleOps; 

/*********************************************************************************/

//派生类“矩形” rectangle
struct Rectangle
{
    struct Shape shape;
    int w;
    int h;
};

//派生类接口
struct Rectangle* RectCreate(int w,int h);
float RectArea(struct Shape *rectangle);
int RectPerimeter(struct Shape *rectangle);
void RectDestory(struct Shape *rectangle);

extern  struct ShapeOps RectangleOps;

 

源文件 Cobject.c

#include "Cobject.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//基类接口
float Area(struct Shape *shape)
{
    assert(shape != NULL);
    return shape->ops->OpsArea(shape);
}

int Perimeter(struct Shape *shape)
{
    assert(shape != NULL);
    return shape->ops->OpsPerimeter(shape);
}

void Destory(struct Shape *shape)
{
    assert(shape != NULL);
    printf("%s Destory\n",shape->typeName);
    shape->ops->OpsDestory(shape);
}

//Triangle 具体接口实现
struct Triangle* TriCreate(int a,int b,int c)
{
    struct Triangle *tri=(struct Triangle *)(malloc(sizeof(struct Triangle)));
    tri->shape.typeName="Triangle";
    tri->shape.ops=&TriangleOps;
    tri->a=a;
    tri->b=b;
    tri->c=c;

    return tri;
}

float TriArea(struct Shape *shape)
{
    struct Triangle *tri;
    assert(shape != NULL);
    tri=(struct Triangle *)(shape);
    return (float)(tri->a * tri->b * tri->c);
}

int TriPerimeter(struct Shape *shape)
{
    struct Triangle *tri;
    assert( shape != NULL);
    tri=(struct Triangle *)shape;
    ;
}

void TriDestory(struct Shape *shape)
{
    struct Triangle *tri;
    assert(shape != NULL);
    tri =(struct Triangle *)shape;
    free(tri);
}

struct ShapeOps TriangleOps={TriArea,TriPerimeter,TriDestory}; 

//Rectangle 具体接口实现
struct Rectangle *RectCreate(int w,int h)
{
    struct Rectangle * rect=(struct Rectangle *)malloc(sizeof(struct Rectangle));
    rect->shape.typeName="Rectangle";
    rect->shape.ops=&RectangleOps;
    rect->w=w;
    rect->h=h;

    return rect;
}

float RectArea(struct Shape *shape)
{
    struct Rectangle *rect;
    assert( shape !=NULL );
    rect=(struct Rectangle *)shape;
    return (float)(rect->h * rect->w );
}

int RectPerimeter(struct Shape *shape)
{
    struct Rectangle *rect;
    assert(shape != NULL );
    rect=(struct Rectangle *)shape;
    *(rect->h + rect->w);
}

void RectDestory(struct Shape *shape)
{
    struct Rectangle *rect;
    assert(shape != NULL);
    rect=(struct Rectangle *)shape;
    free(rect);
}

struct ShapeOps RectangleOps={RectArea,RectPerimeter,RectDestory};

 

测试文件 CobjectTest.cpp

extern "C"{
#include "Cobject.h"
};
#include <iostream>
using namespace std;

int main()
{
    Shape *shape[];

    //创建Triangle
    shape[]=(Shape*)TriCreate(,,);

    //创建Rectangle
    shape[]=(Shape*)RectCreate(,);

    ;i<;i++)
    {
        cout<<"Area: "<<Area(shape[i])<<endl;
        cout<<"Perimeter: "<<Perimeter(shape[i])<<endl;
        Destory(shape[i]);
    }
}

 

注意:

       1、C不支持函数重载,以及函数默认参数

       2、头文件中函数名默认为extern

       3、C++调用C函数,使用extern “C”

C实现面向对象封装、继承、多态的更多相关文章

  1. java面向对象(封装-继承-多态)

    框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...

  2. 浅谈学习C++时用到的【封装继承多态】三个概念

    封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...

  3. 初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)

    JAVA特点: 语法简单,学习容易 功能强大,适合各种应用开发:J2SE/J2ME/J2EE 面向对象,易扩展,易维护 容错机制好,在内存不够时仍能不崩溃.不死机 强大的网络应用功能 跨平台:JVM, ...

  4. 谈CSS模块化【封装-继承-多态】

    第一次听到“CSS模块化”这个词是在WebReBuild的第四届“重构人生”年会上,当时我还想,“哈,CSS也有模块化,我没听错吧?”事实上,我没听错,你也没看错,早就有CSS模块化这个概念了.之所以 ...

  5. JAVA的三大特征 封装继承多态- 简单总结

    简单总结一下 封装-即从很多类的抽取相同的代码 写在一个类里. 好处是 代码的重用,安全. 继承-减少代码的书写. 其好处也是 代码的重用. 多态- 把不同的子类对象都当作父类来看,可以屏蔽不同子类对 ...

  6. C++学习笔记 封装 继承 多态 重写 重载 重定义

    C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...

  7. java类的封装 继承 多态

    1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...

  8. objective-c自学总结(三)---面向对象的封装,继承与多态

    面向对象的三大特性 封装 继承 多态 1.封装: 隐藏属性,方法或实现细节的过程称为封装 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或多种化学 ...

  9. Python全栈--9 __import__ 反射和面向对象基础 self 封装 继承(多继承的顺序) 多态

    一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  10. Java面向对象㈠ -- 封装

    Java的面向对象有三大特征:封装.继承.多态.这里主要对封装进行讲解. 封装可以理解为隐藏一个类的成员变量和成员函数,只对外提供需要提供的成员函数. Java的封装主要通过访问权限控制符:priva ...

随机推荐

  1. showSetPwdDialog--自定义对话框

    样式: 布局: layout dialog_set_pwd.xml <?xml version="1.0" encoding="utf-8"?> & ...

  2. 用C++实现的解数独(Sudoku)程序

    我是一个C++初学者,控制台实现了一个解数独的小程序. 代码如下: //"数独游戏"V1.0 //李国良于2016年11月11日编写完成 #include <iostream ...

  3. salesforce 零基础学习(四十八)自定义列表分页之Pagination基类封装 ※※※

    我们知道,salesforce中系统标准列表页面提供了相应的分页功能,如果要使用其分页功能,可以访问http://www.cnblogs.com/zero-zyq/p/5343287.html查看相关 ...

  4. [bootstrap]bootstrap2如何引导div垂直居中

    参考网址:http://www.4byte.cn/question/138712/bootstrap-how-to-center-vertical.html 部分参考自上面网页中的方法.用过boots ...

  5. 【USACO 3.1】Contact(01子串按出现次数排序)

    题意:给你一个01字符串,将长度为a到b之间(包含a.b)的子串按照出现次数排序.注意输入输出格式 题解:01子串对应一个二进制,为了区别11和011这样的不同子串,我们把长度也记录下来,官方题解是在 ...

  6. Redis总结(一)Redis安装

    最近项目中需要使用Redis,刚好这两天有时间,便总结记录一下Redis的安装,以及如何在.NET中使用Redis. Redis是一个用的比较广泛的Key/Value的内存数据库.目前新浪微博.Git ...

  7. Java classpath 如何自动添加web-content /lib下的jar包

    右键属性--Java build path--Libraries--add library--Web app libraries -- next --next -- ok

  8. .NET软件工程师面试总结

    1.手写画出系统架构图,系统代码架构,有什么技术难点?  2.手写画出系统部署图 CDN(一般购买别人的服务器会自动CDN,他们自己配置就OK啦) 3.asp.net 的session怎么实现会话共享 ...

  9. Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

    目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能---- ...

  10. Inkpad绘图原理浅析

    本文新版本已转移到开源中国,欢迎前往指导. Inkpad是一款非常优秀的iPad矢量绘图软件,保管你一看见就忘不了.我的感觉是“一览众山小”.“相见甚晚”,以至于我写的TouchVG就是“小巫见大巫” ...