问题描述
我现在正在学习 C 中的一些基本多态性。我尝试编写一个常量元素,其中包含一些将被更高级别结构继承的方法指针。在单个文件中编写我的所有代码时它工作正常,这是所需的行为:
#include <stdio.h>
#include <string.h>
struct connection {
void (*connect)(struct connection self);
char name[16];
};
void connection_connect(struct connection self) {
printf("Connecting to %s\n",self.name);
}
const struct connection conn = {connection_connect};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__server;
__server server;
void server_setup(char name[16]) {
strcpy(server.connection.name,name);
}
void server_connect() {
server.connection.connect(server.connection);
}
__server server = {
conn,server_setup,server_connect
};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__client;
__client client;
void client_setup(char name[16]) {
strcpy(client.connection.name,name);
}
void client_connect() {
client.connection.connect(client.connection);
}
__client client = {
conn,client_setup,client_connect
};
int main(void) {
server.setup("Charlie");
client.setup("Delta");
server.connect();
client.connect();
return 0;
}
将所有结构移动到不同文件时会出现问题。在这种情况下,我被迫在连接头文件中extern
struct connection
常量对象:
struct connection {
[...]
};
extern const struct connection conn_o;
然后在.c源文件中定义:
[...]
const struct connection conn_o = {
connection_connect,connection_whereami
};
之后,当我尝试将 conn_o
分配给服务器或客户端的静态定义时,我收到一条错误消息,指出初始化元素不是常量。
例如 server.c 中的初始化器是这样处理的:
__server server = {
conn_o,server_connect
};
是否可以解决这个问题,使 conn_o
在 connection.c
内部初始化后保持不变?
解决方法
感谢@Lundin 的评论。
我开始了解我对编译语言知之甚少。要隐藏结构的实现细节,您必须使用指向隐藏在 .c 文件中的不透明结构的指针。这允许此结构的编译独立性。要访问不透明结构,您只能使用您在头文件中定义的 API 方法(无法遵循此类指针来访问它的实例)。这种技术被称为不透明指针、Pimpl Idiom、桥接模式等。
Wikipedia 提供了多种语言的良好实现来源