免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3491 | 回复: 12

[C] 网上找的C模拟面向对象多态的方法例子,有个错误解决不了,请行家指点 [复制链接]

论坛徽章:
0
发表于 2017-01-18 10:56 |显示全部楼层
附件是相关代码,可以直接编译查看出错点
我测试使用环境是clang

ooc.tar

10.5 KB, 下载次数: 5

论坛徽章:
0
发表于 2017-01-18 11:01 |显示全部楼层
附带说一下,我觉得这段代码并不符合经典的面向对象方式,但是,却显示出了指针的强大灵活。所以,希望这段代码能跑起来,请大神指点

论坛徽章:
0
发表于 2017-01-18 11:09 |显示全部楼层
运行代码会有"Here's the error, in new_.c, why can't invoke draw method in circle?"

论坛徽章:
0
发表于 2017-01-18 11:09 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:36 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧

论坛徽章:
0
发表于 2017-01-18 11:34 |显示全部楼层
自己测试了一下,原来还要验证码下载。那我再贴一遍代码吧。不反对CU市场化,但是能不能将求助类的附件下载去掉啊。

--------------base_.h:
//2017/1/18
//http://dongxicheng.org/cpp/ooc/
#ifndef BASE_H
#define BASE_H

#include <stdarg.h>
#include <stdlib.h>


struct Base{
       
        size_t size;
       
        void *(*constructor)(void *self, va_list *app);
       
        void *(*deConstructor)(void *self);
       
        void (*draw)(const void *self);

};

#endif




---point_.h---------------
//2017/1/18

//Point头文件(对外提供的接口):point.h
#ifndef POINT_H
#define POINT_H

extern const void *Point;///* 使用方法:new (Point, x, y); */

#endif


//Point内部头文件(外面看不到):point.r
#ifndef POINT_R
#define POINT_R

#include "base_.h"

struct PrivatePoint{

        const void* Base;//继承,基类指针,放在第一个位置,const是防止修改
       
        int x, y;

};

#endif

----------circle_.h---------
//2017/1/18

#ifndef CIRCLE_H
#define CIRCLE_H

#include "point_.h"

extern const void *Circle;

struct PrivateCircle{

        struct PrivatePoint* point;//放在第一位,可表继承
       
        int radius;

};

#endif


--------------new_.h
//2017/1/18

#ifndef NEW_H
#define NEW_H

#include <stdio.h>


void *new(const void* class, ...);

void delete(void *item);

void draw(const void* self);

#endif


-------------new_.c------------
//2017/1/18

#include <stdarg.h>
#include "new_.h"
#include "base_.h"
#include "circle_.h"


void *new(const void* _base, ...){
        const struct Base* base = _base;
        void *p = calloc(1, base->size);
        *(const struct Base**)p = base;
        if(base->constructor){
                va_list ap;
                va_start(ap, _base);
                p = base->constructor(p, &ap);
                va_end(ap);
        }
        return p;
}

void delete(void* self){
        //why do I have to use cp here?
        const struct Base** cp = self;
        if(self && cp && (*cp)->deConstructor){
                self = (*cp)->deConstructor(self);
        }else{
                printf("No DeConstructor\n");
        }
        free(self);
}

void draw(const void* self){
        printf("new: draw\n");
        //Is this right?
        const struct Base *const* cp = self;
        //Here's the error, why can't invoke draw method in circle?
        if((*cp)->draw){
                (*cp)->draw(self);
        }else{
                printf("Here's the error, in new_.c, why can't invoke draw method in circle?\n");
                const struct PrivateCircle* pc = self;
                printf("In new: draw: x = %d\n", pc->point->x);
                printf("No Draw defined\n");

        }
}




------point_.h---------
//2017/1/18

#include <stdarg.h>
#include <stdio.h>

#include "point_.h"
#include "new_.h"

static void* pointConstructor(void* _self, va_list *app){
        struct PrivatePoint* self = _self;
        self->x = va_arg(*app, int);
        self->y = va_arg(*app, int);
        return self;
}

static void pointDraw(const void* _self){
        const struct PrivatePoint* self = _self;
        printf("Point draw: %d, %d\n", self->x, self->y);
}

static const struct Base _Point = {
        sizeof(struct PrivatePoint), pointConstructor, 0, pointDraw
};

//Check to make sure "type" itself is also an address
const void* Point = &_Point;



----------------circle_.c--------------
//2017/1/18

#include <stdio.h>

#include "point_.h"
#include "circle_.h"
#include "new_.h"

static void* circleConstructor(void* _self, va_list *app){
        struct PrivateCircle* self = _self;
        //must add "struct", otherwise: use of undeclared identifier 'PrivatePoint'
        //must malloc first, otherwise: Segmentation fault (core dumped)
        self->point = malloc(sizeof(struct PrivatePoint));
        self->point->x = va_arg(*app, int);
        self->point->y = va_arg(*app, int);
        self->radius = va_arg(*app, int);
        printf("Circle Constructor: %d, %d, %d\n", self->point->x, self->point->y, self->radius);
        return self;
}

static void circleDraw(const void* _self){
        const struct PrivateCircle* self = _self;
        printf("Circle draw: %d, %d, %d\n", self->point->x, self->point->y, self->radius);
}

static const struct Base _Circle = {
        sizeof(struct PrivateCircle), circleConstructor, 0, circleDraw
        //sizeof(struct PrivateCircle), circleConstructor, 0, 0
};

const void* Circle = &_Circle;

------------main.c------------
//2017/1/18
#include "point_.h"
#include "circle_.h"


int main(){
        void* p1 = new(Point, 1, 2);
        void* p2 = new(Circle, 3, 4, 5);

        draw(p1);
//Circle has error       
        draw(p2);

        delete(p1);
//        delete(p2);
}

论坛徽章:
0
发表于 2017-01-18 11:34 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:35 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧

论坛徽章:
0
发表于 2017-01-18 11:35 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:35 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧

论坛徽章:
0
发表于 2017-01-18 11:35 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:37 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧

论坛徽章:
0
发表于 2017-01-18 11:53 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:37 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧

论坛徽章:
0
发表于 2017-01-18 12:02 |显示全部楼层
本帖最后由 xflltw 于 2017-01-18 17:38 编辑

提交故障,重复发帖,不知怎么删楼,编辑一下吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP