Как я вызываю мыс константы памяти, на которую указывает obj-> val1 в функции 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;
}
Код здесь симпатичен сам explanitory. Я должен смочь сделать объект неконстанты и заполнить его данными, но затем передать его функции, где эти данные не могут быть изменены. Как я могу пойти об этом?
Я знаю, что могу просто передать в указателе интервала константы, но теоретически, этот класс содержит несколько других указателей, в которых я буду нуждаться в "fn" также.
Спасибо,
Griff
Поскольку вы отметили как C ++, вы можете сделать член закрытым
и создать метод доступа, который возвращает const int *
. Первоначально вы могли установить член через конструктор или функцию friend
.
Я не специалист по C++, но в C я бы сделал это через два разных объявления struct, один публичный, другой приватный:
#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;
}
Когда я пытаюсь скомпилировать вышеприведенное в 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’
Вы действительно не можете. 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 мог быть создан.