让struct不可变有什么意义吗?
由于我是从更高级别的Java来到C的,我们没有像让struct不可变有什么意义吗?,c,struct,constants,C,Struct,Constants,由于我是从更高级别的Java来到C的,我们没有像const这样的类型quialifier,为了使一个类型不可变,我们必须声明它的所有成员为final,并确保成员本身是不可变的 根据合同,在C中我们有quialifierconst类型 更具体地说,让我举一个我目前一直坚持的例子。我有以下几点 application.h: struct application_config_t{ int poll_interval; int compression_ratio; //othe
const
这样的类型quialifier,为了使一个类型不可变,我们必须声明它的所有成员为final,并确保成员本身是不可变的
根据合同,在C中我们有quialifierconst
类型
更具体地说,让我举一个我目前一直坚持的例子。我有以下几点
application.h
:
struct application_config_t{
int poll_interval;
int compression_ratio;
//other config parameters
};
struct application_t{ //This structure make me confused
void (*run_application)(struct application_t*);
void (*stop_application)(struct application_t*);
};
struct application_t* create_app(const struct application_config_t);
void release_app(struct application_t*);
我不确定如何定义应用程序\u t
结构。它的唯一用途是使用run\u应用程序执行actaul运行,并使用stop\u应用程序处理SIGINT
以执行正常关闭,然后在stop\u应用程序
后返回调用release\u app(struct application\t*)
以释放内存
我可以选择以下案例:
I。不可变的应用程序\u t
struct application_t{
void (*const run_application)(struct application_t*);
void (*const stop_application)(struct application_t*);
}
我认为这很好,因为一旦创建了应用程序,就不应该修改它。但是创建这样一个不可变的结构将需要memcpy
调用
II。创建应用程序时可更改的应用程序\u t
,将声明为
const struct application_t* create_app(const struct application_config_t);
这很好,但我想在stop\u应用程序返回后释放struct application\u t*
指向的内存。释放struct application\u t*
意味着application\u t
实际上不是const
。和用法一样
struct application_config_t cfg;
//...
const struct application_t *app_ptr = create_app(cfg);
(app_ptr -> run_application)(app_ptr);
release_app((struct application_t *) app_ptr); //const cast
需要对const
ness施法
释放struct application_t*意味着application并不是真正的常量
实际上是的。客户端代码无法对其进行变异,并且在将其移交给release\u app
之后,不应进一步使用它。它在其整个生命周期中都是const
,如果release\u app
通过指向const的指针接受,则它在语义上是正确的(只需在release\u app
中进行转换)
为什么我说它在语义上是正确的?因为当create\u app
为结构分配空间并初始化它时,它不是const
,是吗?const
稍后作为合同的一部分添加。因此,在release\u app
中接受常量指针只是遵循您已经建立的相同契约。API对知道存储可以改变这一事实并没有破坏契约。因为当create\u app为结构分配空间并对其进行初始化时,它不是常量,不是吗?我有个问题。如果我们声明const struct application\u t*create\u app(const struct application\u config\t)代码>和无效发布应用程序(const struct application_t*)代码>我们需要以下合同:“一旦创建应用程序,在发布之前不能修改它”这有什么意义吗?在这里create\u app
返回const
以防止它在创建后立即被修改。@SomeName-这就是您想要的合同。至少我是这样理解你的问题的。所以是的,把它编成相关的类型是有意义的。我甚至会更进一步,说不这样做是没有意义的。如果只返回一个const应用程序*
,那么用户代码如何获得指向非const版本的指针,除非以某种方式破坏了契约?