所以只是为了“有趣”,我决定使用指针函数在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:
#include "obj.h"
void readValue(struct Obj* this_);
void setValue (struct Obj* this_, int mValue_);
struct pObjVar{
int mValue;
};
struct Obj* newObj(){
struct Obj* tmp = (struct Obj*) malloc(sizeof(struct Obj));
tmp->pVar = (struct pObjVar*) malloc(sizeof(struct pObjVar));
tmp->pVar->mValue = 0;
tmp->read = readValue;
tmp->set = setValue;
return tmp;
}
void deleteObj(struct Obj **obj){
free((*obj)->pVar); (*obj)->pVar = NULL;
free((*obj)); *obj = NULL;
}
void readValue(struct Obj *this_){
printf("Value = %d\n",this_->pVar->mValue);
}
void setValue(struct Obj *this_, int mValue_){
this_->pVar->mValue = mValue_;
}
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
函数。如果要在内部将指针设置为deleteObj
,则只需要NULL
。
答案 0 :(得分:3)
另一种写作方式:
#define member(FUNC, ...) FUNC(this_, ## __VA_ARGS__)
int reader(struct Obj *_this) {
member(read, a, b, c);
member(getch);
return 0;
}
这可以用于实现接口,继承和许多C ++功能,这些功能在C with Classes次中实现。在Linux内核中,文件操作是这样实现的。文件结构存储指向函数的指针,以便每个文件系统都可以存储它自己的系统调用处理程序,这些处理程序在结构中的数据上运行。
答案 1 :(得分:1)
不,没有办法在C中自动执行此操作。标准预处理器无法胜任转换。
现在还有一种功能可以发现它被称为a->func(10)
。在函数内部只有func(10)
。
当Bjarne Stroustrup开始设计C ++时,他为此编写了一个特殊的预处理器/编译器Cfront。
实际上,C ++并不真正存储指向(非虚拟)函数的指针。它只是在编译代码时将a->set(10)
转换为类似struct_Obj_set(a, 10)
的内容。