标题:网上找的C模拟面向对象多态的方法例子,有个错误解决不了,请大神指点
取消只看楼主
xflltw
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2017-1-18
结帖率:0
已结贴  问题点数:20 回复次数:0 
网上找的C模拟面向对象多态的方法例子,有个错误解决不了,请大神指点

我测试使用环境是clang
运行代码会有"Here's the error, in new_.c, why can't invoke draw method in circle?"
附带说一下,我觉得这段代码并不符合经典的面向对象方式,但是,却显示出了指针的强大灵活。所以,希望这段代码能跑起来,请大神指点

--------------base_.h:
//2017/1/18
//http://
#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);
}

搜索更多相关主题的帖子: include method 经典的 网上 
2017-01-18 11:59



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-473678-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023089 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved