2010-07-04 17 views
8

मैं फ़ंक्शन 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; 
} 

यहां कोड बहुत आत्म व्याख्यात्मक है। मुझे एक गैर-कॉन्स्ट ऑब्जेक्ट बनाने और डेटा के साथ भरने में सक्षम होना चाहिए, लेकिन फिर इसे उस फ़ंक्शन पर पास करें जहां यह डेटा संशोधित नहीं किया जा सकता है। मैं इसके बारे में कैसे जा सकता हूं?

मुझे पता है कि मैं सिर्फ एक कॉन्स इंट पॉइंटर में पास कर सकता हूं, लेकिन सैद्धांतिक रूप से, इस वर्ग में कई अन्य पॉइंटर्स हैं जिन्हें मुझे "एफएन" में भी आवश्यकता होगी।

धन्यवाद,

Griff

उत्तर

6

जब से तुम C++ में चिह्नित है, तो आप सदस्य private बनाने और एक्सेसर कि एक const int * रिटर्न बना सकता है। आप मूल रूप से सदस्य को अपने कन्स्ट्रक्टर या friend फ़ंक्शन के माध्यम से सेट कर सकते हैं।

+0

अहह। मैं भूल जाता हूं कि सी ++ में structs में विधियों और सदस्य चर हो सकते हैं। इससे मेरी समस्या हल हो जाएगी, यद्यपि केवल गिगल्स के लिए, क्या सी में ऐसा करना संभव है? – Griffin

+0

@ ग्रिफिन: यदि आप वास्तव में यह सुनिश्चित करना चाहते थे कि आप शायद इसे अलग से पास कर दें। –

+0

@ ग्रिफिन: हाँ। मेरा उत्तर देखें, जो सी और सी ++ दोनों के लिए मान्य है। –

2

आप वास्तव में नहीं कर सकते हैं। एक कॉन्स फू निर्दिष्ट करता है कि अंदर के सदस्य कॉन्स्ट हैं, यानी, वे पूर्णांक के निरंतर पॉइंटर्स हैं, न कि निरंतर पूर्णांक के लिए पॉइंटर्स।

इसका उचित समाधान इन सदस्यों को छिपाने और सार्वजनिक इंटरफ़ेस प्रदान करने के माध्यम से encapsulation के माध्यम से होगा।

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 सेट किया जा सकता, उचित कंस्ट्रक्टर्स, आदि बनाने के लिए की आवश्यकता होगी: एक व्यावहारिक समाधान, आप निजी वंशानुक्रम के माध्यम से किया जाएगा struct foo को संशोधित करने के लिए मना किया जाना चाहिए, अप।

+0

लगता है कि मुझे अपनी खराब छोटी संरचना में कुछ अतिरिक्त जटिलता जोड़नी होगी। सूचनात्मक कोड नमूना के लिए धन्यवाद! – Griffin

4

मैं एक सी ++ व्यक्ति नहीं हूँ, लेकिन सी में, मैं दो अलग अलग 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; 
} 

जब मैं ऊपर w/जीसीसी संकलन करने की कोशिश , मुझे निम्न संकलक त्रुटियां मिलती हैं, क्योंकि मैं केवल पढ़ने योग्य स्मृति को संशोधित करने का प्रयास कर रहा हूं:

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

ओउओ .. अब वह चालाक है। आप के लिए कुडोस, महोदय। मैं इसे अपने चाल के बैग में जोड़ रहा हूं। – Griffin

संबंधित मुद्दे