2010-07-04 16 views
8

Come si forza la constanza della memoria puntata da obj-> val1 nella funzione fn?C/C++: Puntatori all'interno di Const Struct

#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; 
} 

Il codice qui è piuttosto auto-esplicativo. Devo essere in grado di creare un oggetto non const e riempirlo con i dati, ma poi passarlo a una funzione in cui questi dati non possono essere modificati. Come posso andare su questo?

So che posso passare solo un puntatore const int, ma in teoria questa classe contiene molti altri puntatori che avrò bisogno anche in "fn".

Grazie,

Griff

risposta

6

Dal momento che nella categoria C++, si potrebbe fare il membro private e fare una funzione di accesso che restituisce un const int *. È possibile originariamente impostare il membro tramite il costruttore o una funzione friend.

+0

Ahh. Dimentico che le strutture in C++ possono avere metodi e variabili membro. Questo risolverà il mio problema, anche se solo per ridacchiare, è possibile farlo in C? – Griffin

+0

@Griffin: Se davvero volevi assicurarti che probabilmente lo inoltrerai separatamente. –

+0

@Griffin: sì. Vedi la mia risposta, che è valida sia per C che per C++. –

2

Non puoi davvero. Un const foo specifica che i membri all'interno sono const, cioè sono puntatori costanti agli interi, non puntatori agli interi costanti.

La soluzione corretta sarebbe attraverso l'incapsulamento, nascondendo questi membri e fornendo un'interfaccia pubblica. Una soluzione pratica, dovrebbe essere vietato modificare il foo struct, sarebbe attraverso l'ereditarietà privata:

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; } 
}; 

Naturalmente, si avrebbe bisogno di creare i costruttori appropriati, ecc, in modo che il foo originale può essere impostato su.

+0

Sembra che dovrò aggiungere un po 'di complessità in più alla mia povera piccola struttura. Grazie per l'esempio di codice informativo! – Griffin

4

Io non sono una persona ++ C, ma in C, mi piacerebbe gestire questo attraverso due diverse dichiarazioni struct, uno pubblico, uno privato:

#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; 
} 

Quando provo a compilare il sopra w/GCC , Ottengo i seguenti errori del compilatore, poiché sto cercando di modificare la memoria di sola lettura:

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

Oooo .. Ora è intelligente. Complimenti a te, signore. Sto aggiungendo questo alla mia borsa di trucchi. – Griffin

Problemi correlati