在多个文件中使用常量元素的多态结构

问题描述

我现在正在学习 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_oconnection.c 内部初始化后保持不变?

解决方法

感谢@Lundin 的评论。

我开始了解我对编译语言知之甚少。要隐藏结构的实现细节,您必须使用指向隐藏在 .c 文件中的不透明结构的指针。这允许此结构的编译独立性。要访问不透明结构,您只能使用您在头文件中定义的 API 方法(无法遵循此类指针来访问它的实例)。这种技术被称为不透明指针、Pimpl Idiom、桥接模式等。

Wikipedia 提供了多种语言的良好实现来源

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...