c - 使用指针函数模拟 C 结构中的成员函数

标签 c

因此,为了“好玩”,我决定使用指针函数在 C 中模拟 C++ 成员函数。这是一个简单的代码:

对象.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

对象.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_;
}

主.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 指针显式传递给我的成员函数来模拟隐式指针的作用。我想这很好用,除了它让整个事情看起来很奇怪!

如果我想传递对象,为什么要将函数实现为成员函数?我找到的唯一答案可能是在你想要一个统一的接口(interface)但有多种实现的情况下? (与 C++ 虚函数类似的东西?)

模拟成员函数的其他原因是什么(如果有的话)?另外,有什么办法可以完全避免传递显式 this_ 指针吗?

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

最佳答案

另一种写法:

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

这可用于实现接口(interface)、继承和许多 C++ 功能,这些功能在 C with Classes 时代都是这样实现的。在Linux内核中,文件操作是这样实现的。文件结构存储指向函数的指针,因此每个文件系统都可以存储它自己的系统调用处理程序,这些处理程序对结构中的数据进行操作。

关于c - 使用指针函数模拟 C 结构中的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9784884/

相关文章:

c - 不断收到错误 : "redefinition of typedef ' MYSTRUCT '"and "previous declaration of 'MYSTRUCT' was here"

c - MessageBox 在处理来自 DialogBox 的 WM_DESTROY 事件时不起作用

c - 二分查找 - 如果我从列表中间添加或减去 "1",我会得到中间数字左边的第一个数字还是一个数值?

c - 如何确定 C 数组中的元素是否尚未分配给任何东西?

c - 动态跳转到 C 中的标签

c++ - 为RealBasic创建与C/C++库的绑定(bind)

c - Uart 16c950 linux 速度高于 B4000000 (4Mbps)

mysql - undefined symbol : mysql_options problem

c - 递归获取目录的大小 - C

c - 从txt文件中获取变量