C / C ++:Const Struct中的指针

时间:2010-07-04 23:11:40

标签: c++ c pointers struct const

如何在函数fn中强制obj-> val1指向的内存的常量?

#include <iostream>

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

void fn( const foo* obj )
{
    // I don't want to be able to change the integer that val1 points to
    //obj->val1 = new int[20]; // I can't change the pointer,
    *(obj->val1) = 20; // But I can change the memory it points to...
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    foo stoben;
    stoben.val1 = new int;
    *(stoben.val1) = 0;
    std::cout << *(stoben.val1) << std::endl; // Output is "0"
    fn( &stoben );
    std::cout << *(stoben.val1) << std::endl; // Output is "20"
    delete stoben.val1;
    return 0;
}

这里的代码非常自我解释。我需要能够创建一个非const对象并用数据填充它,然后将其传递给无法修改此数据的函数。我怎么能这样做呢?

我知道我可以传入一个const int指针,但理论上,这个类还包含其他几个指针,我也需要它们在“fn”中。

谢谢,

格里夫

3 个答案:

答案 0 :(得分:6)

由于您标记为C ++,因此您可以创建成员private并创建一个返回const int *的访问者。您最初可以通过构造函数或friend函数设置成员。

答案 1 :(得分:4)

我不是C ++人,但在C中,我会通过两个不同的结构声明来处理这个问题,一个是公共的,一个是私有的:

#include <stdio.h>
#include <stdlib.h>

struct private_foo {
    int* val1;
    int* val2;
    int* val3;
};

struct public_foo {
    int const * const val1;
    int const * const val2;
    int const * const val3;
};


void fn( struct public_foo * obj )
{
    int local;
    *(obj->val1) = 20; // compile error
    obj->val1 = &local; // compile error
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    struct private_foo stoben;
    stoben.val1 = malloc(sizeof(int));
    if (!stoben.val1) { return -1; }
    *(stoben.val1) = 0;
    printf("%d", *(stoben.val1) );
    fn( (struct public_foo *) &stoben );
    printf("%d", *(stoben.val1) );
    free(stoben.val1);
    return 0;
}

当我尝试编译上面的w / GCC时,我得到以下编译器错误,因为我正在尝试修改只读内存:

temp.c: In function ‘fn’:
temp.c:20: error: assignment of read-only location
temp.c:21: error: assignment of read-only member ‘val1’

答案 2 :(得分:2)

你真的不能。 const foo指定里面的成员是const,也就是说,它们是整数的常量指针,而不是指向常量整数的指针。

对此的正确解决方案是通过封装,隐藏这些成员并提供公共接口。一个实用的解决方案,如果你被禁止修改struct foo,将通过私有继承:

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

struct constFoo : private foo {
public:
   const int* getVal1() { return val1; }
   const int* getVal2() { return val2; }
   const int* getVal3() { return val3; }
};

当然,您需要创建适当的构造函数等,以便可以设置原始foo。