首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指向const结构的指针,仍然可以修改成员吗?

指向const结构的指针,仍然可以修改成员吗?
EN

Stack Overflow用户
提问于 2018-08-10 07:12:15
回答 5查看 4.7K关注 0票数 14

我有一个结构,我想通过一些回调函数传递给一些外部的c代码,它们在我的程序中注册。不过,我想把这个结构当作只读结构。我担心的是,它们仍然可以修改我所传递的原始结构中指向的结构。用下面的小例子说明:

代码语言:javascript
复制
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);
}

那么,如何改进我的代码设计,使它们不能修改我传递的结构呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-08-10 07:43:54

若要正确处理此情况,只能使用前向声明将成员与getter和setter函数一起隐藏。

集中注意下面的代码并检查:

  • struct s1只有前向声明,所以您可以在struct s2中创建指向它的指针。
  • struct s1的实际实现是在mylib.c中,因此所有成员只对库可见,而不对用户可见。
  • 实现Getters和setter是为了设置/读取这些隐藏成员的值,因为只有您的库可以访问成员,从而使其完全隐藏在用户面前。
  • 这迫使他使用你的功能。

没药:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
#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.主要:

代码语言:javascript
复制
#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,或者您有未定义的行为。

票数 9
EN

Stack Overflow用户

发布于 2018-08-10 07:32:22

你不能。即使您按值传递struct s2,也会在函数中得到一个指向非const struct s1的指针,这仅仅是因为它是s2在其定义中包含的内容。

一旦有了指向非const对象的指针,就可以更改该对象。我在这里的意思和其他答案的意思是,它不是语言问题--更确切地说,语言对你来说没有任何意义--而是一个设计问题。如果出于任何原因不能接受struct s1可以从f更改,那么您必须找到一个不同的设计,其中您不传递一个非const指针到它,不管它是否是一个结构的成员。在这里,一个简单的方法是传递给个人成员:

代码语言:javascript
复制
void f(int x, const struct s1 *y) {
    y->a = 20;  // error
}

这可能不是你所期望的,但这是我对C语言所能说的最好的。

票数 5
EN

Stack Overflow用户

发布于 2018-08-10 07:19:00

您可以更改第二个struct声明如下:

代码语言:javascript
复制
struct s2 {
    int x;
    struct s1 const *y;
};

添加的const确保y是只读的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51780954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档