C / C ++: указатели в Const Struct - PullRequest
8 голосов
/ 05 июля 2010

Как мне принудительно установить константу памяти, на которую указывает 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;
}

Код здесь довольно понятен. Мне нужно иметь возможность создать неконстантный объект и заполнить его данными, но затем передать его в функцию, где эти данные не могут быть изменены. Как я могу пойти по этому поводу?

Я знаю, что могу просто передать указатель на const int, но теоретически этот класс содержит несколько других указателей, которые мне также понадобятся в "fn".

Спасибо

Griff

Ответы [ 3 ]

6 голосов
/ 05 июля 2010

Поскольку вы пометили как C ++, вы можете сделать элемент private и создать метод доступа, который возвращает const int *. Изначально вы можете установить член с помощью вашего конструктора или функции friend.

4 голосов
/ 05 июля 2010

Я не человек 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;
}

Когда я пытаюсь скомпилировать вышеприведенное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 голосов
/ 05 июля 2010

Вы действительно не можете.Const foo указывает, что члены внутри являются const, то есть они являются постоянными указателями на целые числа, а не указателями на постоянные целые числа.

Надлежащим решением этого будет инкапсуляция, скрытие этих членов и предоставление общедоступныхинтерфейс.Практическое решение, если вам будет запрещено изменять структуру 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 могбыть настроенным.

...