2012-03-20 51 views
3

所以,如果有'有趣',我决定使用指针函数在C中模拟C++成员函数。下面是一个简单的代码:使用指针函数来模仿C结构中的成员函数

obj.h:

#ifndef OBJ_H 
#define OBJ_H 

#include <stdlib.h> 
#include <stdio.h> 

struct Obj{ 
    struct pObjVar* pVar; 

    void (*read)(struct Obj*); 
    void (*set) (struct Obj*, int); 
}; 

struct Obj* newObj(); 
void deleteObj(struct Obj** obj); 

#endif 

obj.c:

​​

main.c中:

#include "obj.h" 

int main(void) 
{ 
    struct Obj* a = newObj(); 
    a->set(a, 10); 
    a->read(a); 
    deleteObj(&a); 

    return 0; 
} 

输出:

>./a.out 
Value = 10  

然而,在这样做的时候,我想我必须通过明确地将它传递给我的成员函数来仿效隐式指针this的作用。我猜,这工作正常,除了它使整个事情看起来很奇怪!

如果我想传递对象,为什么要实现函数作为成员函数?我发现它的唯一答案可能是你想要一个统一的界面,但各种实现? (类似C++虚拟函数?)

什么是(如果有)某些其他原因来模仿成员函数?此外,有没有办法避免通过显式的this_指针呢?

编辑:传递对象时原始代码存在问题。我错误地将&a用于read/set函数。如果您想要在内部将指针设置为NULL,则只需要deleteObj

+1

您正在传递指向函数的_address_,即'Obj **'。跳过函数调用中的&&。 – 2012-03-20 10:26:04

+0

@JoachimPileborg:你是对的。请参阅我的编辑 – GradGuy 2012-03-20 10:38:05

+0

我曾经不得不使用类似的方法维护一个遗留项目,具有复杂的继承层次,并且使用不透明的typedef'ed int值而不是指向结构的指针。不用说,调试/维护是一场噩梦! – SirDarius 2012-03-20 10:44:21

回答

3

只是写的另一种方式:

#define member(FUNC, ...) FUNC(this_, ## __VA_ARGS__) 
int reader(struct Obj *_this) { 
    member(read, a, b, c); 
    member(getch); 
    return 0; 
} 

这可用于实现接口,继承和许多C++功能,它实现了这样的带类的C倍。在Linux内核中,文件操作是这样实现的。文件结构存储指向函数的指针,以便每个文件系统可以存储它自己的系统调用处理程序,这些处理程序在结构中的数据上运行。

1

不,在C中无法自动执行此操作。标准预处理器无法胜任转换。

现在还有一种方法可以找到它被称为a->func(10)的功能。在功能里面它只是func(10)。当Bjarne Stroustrup开始设计C++时,他为此编写了一个特殊的预处理器/编译器Cfront

实际上,C++并不真正存储指向(非虚拟)函数的指针。它只是在编译代码时将a->set(10)转换为类似struct_Obj_set(a, 10)的东西。