我有一个结构,我想通过一些回调函数传递给一些外部的c代码,它们在我的程序中注册。不过,我想把这个结构当作只读结构。我担心的是,它们仍然可以修改我所传递的原始结构中指向的结构。用下面的小例子说明:
struct s1 {
int a;
int b;
};
struct s2 {
int x;
struct s1 *y;
};
void f(const struct s2 *o)
{
//o->x=10; //error
o->y->a=20; //no error
o->y->b=30; //no error
}
int main()
{
struct s1 o1 = {10, 20};
struct s2 o2 = {30, &o1};
f(&o2);
}那么,如何改进我的代码设计,使它们不能修改我传递的结构呢?
发布于 2018-08-10 07:43:54
若要正确处理此情况,只能使用前向声明将成员与getter和setter函数一起隐藏。
集中注意下面的代码并检查:
struct s1只有前向声明,所以您可以在struct s2中创建指向它的指针。struct s1的实际实现是在mylib.c中,因此所有成员只对库可见,而不对用户可见。没药:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2 {
int x;
struct s1* y;
};
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */mylib.c:
#include "mylib.h"
//Now implement structure
struct s1 {
int a, b;
};
//Make getter
int
get_a_from_s1(struct s2* s) {
return s->y->a;
}
//Make setter
void
set_a_to_s1(struct s2* s, int a) {
s->y->a = a;
}C.主要:
#include <stdio.h>
#include "mylib.h"
int main(void) {
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %d\r\n", a);
return 0;
}当然,请确保->y不是NULL,或者您有未定义的行为。
发布于 2018-08-10 07:32:22
你不能。即使您按值传递struct s2,也会在函数中得到一个指向非const struct s1的指针,这仅仅是因为它是s2在其定义中包含的内容。
一旦有了指向非const对象的指针,就可以更改该对象。我在这里的意思和其他答案的意思是,它不是语言问题--更确切地说,语言对你来说没有任何意义--而是一个设计问题。如果出于任何原因不能接受struct s1可以从f更改,那么您必须找到一个不同的设计,其中您不传递一个非const指针到它,不管它是否是一个结构的成员。在这里,一个简单的方法是传递给个人成员:
void f(int x, const struct s1 *y) {
y->a = 20; // error
}这可能不是你所期望的,但这是我对C语言所能说的最好的。
发布于 2018-08-10 07:19:00
您可以更改第二个struct声明如下:
struct s2 {
int x;
struct s1 const *y;
};添加的const确保y是只读的。
https://stackoverflow.com/questions/51780954
复制相似问题