C/C++: Pointers within Const Struct
How do I force const-ness of the memory pointed to by obj->val1 in the function fn?
#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;
}
The code here is pretty self explanitory. I need to be able to make a non-const object and fill it with data, but then pass it to a function where this data cannot be modified. How can I go about this?
I know I can just pass in a const int pointer, but theoretically, this class contains several other pointers which I will need in "fn" as well.
T开发者_运维知识库hanks,
Griff
Since you tagged as C++, you could make the member private
and make an accessor that returns a const int *
. You could originally set the member via your constructor or a friend
function.
I'm not a C++ person, but in C, I'd handle this through two different struct declarations, one public, one private:
#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;
}
When I try to compile the above w/ GCC, I get the following compiler errors, since I'm trying to modify read-only memory:
temp.c: In function ‘fn’:
temp.c:20: error: assignment of read-only location
temp.c:21: error: assignment of read-only member ‘val1’
You really can't. A const foo specifies that the members inside are const, that is, they are constant pointers to integers, not pointers to constant integers.
The proper solution to this would be via encapsulation, hiding these members and providing a public interface. A practical solution, should you be forbidden to modify the struct foo, would be through private inheritance:
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; }
};
Of course, you would need to create the appropriate constructors, etc., so that the original foo can be set up.
精彩评论