【发布时间】:2018-06-12 16:45:21
【问题描述】:
为了尝试封装结构成员(以与this 问题中讨论的类似方式),我创建了以下代码。
在下面的代码中,我有一个 c-struct,其中包含访问隐藏的结构成员的方法(通过被强制转换为其他相同但没有隐藏属性的结构)
#include <stdio.h>
typedef struct class {
int publicValue;
int (*getPV)();
void (*setPV)(int newPV);
} class;
typedef struct classSource {
int publicValue;
int apv;
int (*getPV)();
void (*setPV)(int newPV);
int PV;
} classSource;
class class_init() {
classSource cs;
cs.publicValue = 15;
cs.PV = 8;
int class_getPV() {
return cs.PV;
};
void class_setPV(int x) {
cs.PV = x;
};
cs.getPV = class_getPV;
cs.setPV = class_setPV;
class *c = (class*)(&cs);
return *c;
}
int main(int argc, const char * argv[]) {
class c = class_init();
c.setPV(3452);
printf("%d", c.publicValue);
printf("%d", c.getPV());
return 0;
}
当我运行它时,我得到一个分段错误错误。但是,我注意到如果我注释掉某些代码行,它(似乎)可以正常工作:
#include <stdio.h>
typedef struct class {
int publicValue;
int (*getPV)();
void (*setPV)(int newPV);
} class;
typedef struct classSource {
int publicValue;
int apv;
int (*getPV)();
void (*setPV)(int newPV);
int PV;
} classSource;
class class_init() {
classSource cs;
cs.publicValue = 15;
cs.PV = 8;
int class_getPV() {
return cs.PV;
};
void class_setPV(int x) {
cs.PV = x;
};
cs.getPV = class_getPV;
cs.setPV = class_setPV;
class *c = (class*)(&cs);
return *c;
}
int main(int argc, const char * argv[]) {
class c = class_init();
c.setPV(3452);
//printf("%d", c.publicValue);
printf("%d", c.getPV());
return 0;
}
我认为这可能与使用初始化程序将 getter 和 setter 方法添加到结构中有关,因为它们可能会覆盖内存。
我在做什么未定义的行为?有没有办法解决这个问题?
编辑:在下面的答案的帮助下,我重新编写了代码。如果有人想查看实现,下面是修改后的代码
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int pub;
} class;
typedef struct {
class public;
int PV;
} classSource;
int class_getPV(class *c) {
return ((classSource*)c)->PV;
}
void class_setPV(class *c, int newPV) {
((classSource*)c)->PV = newPV;
}
class *class_init() {
classSource *cs = malloc(sizeof(*cs));
if((void*)cs == (void*)NULL) {
printf("Error: malloc failed to allocate memory");
exit(1);
}
cs->public.pub = 10;
cs->PV = 8;
return &(cs->public);
}
int main() {
class *c = class_init();
class_setPV(c,4524);
printf("%d\n",class_getPV(c));
printf("%d\n",c->pub);
free(c);
return 0;
}
【问题讨论】:
-
@UnholySheep 它实际上返回了取消引用的
c。所以我不清楚整个带有指针的练习。可能是为了解决class和classSource之间的不兼容问题。约翰,你为什么认为你可以退回一个而不是另一个? -
您的结构不兼容。也许您可以在第一个字段中逃脱,但其余部分则不行。
-
您正在为函数指针分配嵌套函数,这是非标准 C(不允许嵌套函数)。所以我真的不知道它的行为,但可以想象这些可能表现为局部变量,不能从函数外部访问。
-
C 没有类:你一半使用 C,一半使用 C++。
-
这里的一切都是未定义的行为。强制转换不能这样工作,嵌套函数不能这样工作(实际上标准 C 根本没有嵌套函数,你(错误)使用了非标准编译器扩展),没有闭包,你不能返回本地对象的地址。您可以在 C 中执行 OOP,但您无法修复您的代码。我会说你需要忘掉你学错的东西并重新开始。推荐你获取X Toolkit Intrinsics的源码,好好研究一下。
标签: c oop struct segmentation-fault