Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
让struct不可变有什么意义吗?_C_Struct_Constants - Fatal编程技术网

让struct不可变有什么意义吗?

让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

由于我是从更高级别的Java来到C的,我们没有像
const
这样的类型quialifier,为了使一个类型不可变,我们必须声明它的所有成员为final,并确保成员本身是不可变的

根据合同,在C中我们有quialifier
const
类型

更具体地说,让我举一个我目前一直坚持的例子。我有以下几点

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版本的指针,除非以某种方式破坏了契约?