2017-05-09 13 views
6

से मैं इस तरह एक सी संरचना है:सी - अनुकरण 'परिवर्तनशील' सी ++

struct my_struct { 
    int i; 
    double d; 
    struct expensive_type * t; 
}; 

इस संरचना का एक उदाहरण बनाया है और के रूप में आरंभ नहीं हो जाता:

struct my_struct * my_new(int i , double d) 
{ 
    struct my_struct * s = malloc(sizeof * s); 
    s->i = i; 
    s->d = d; 
    s->t = NULL; 
    return s; 
} 

struct expensive_type * t सदस्य गिना जा रहा है काफी है महंगा, और इसकी आवश्यकता नहीं हो सकती है - यह केवल NULL के लिए शुरू किया गया है - और बाद में मांग पर गणना की गई:

const struct expensive_type * my_get_expensive(const struct my_struct * s) 
{ 
    if (!s->t) 
     s->t = my_expensive_alloc(s->i , s->d); 
    return s->t; 
} 

C++ में मैं struct expensive_type * सदस्य पर mutable इस्तेमाल किया गया होगा, यह संभव स्थानीय स्तर पर स्थिरांक दूर कास्टिंग सी में कुछ इसी तरह, यानी प्राप्त करने के लिए है:

{ 
    struct my_struct * mutable_s = (struct my_struct*) s; 
    mutable_s->t = ...; 

}

या हस्ताक्षर में const को हटा रहा है मेरा एकमात्र मानक-अनुरूप विकल्प?

struct expensive; // Forward declaration, ignore 
// One could also use a struct expensive * (a pointer) instead 
// of this structure. IMO giving it a name is the better option. 
struct expensive_handle { 
    struct expensive * target; 
}; 

// Store the simple data members as usual, store a pointer to a 
// handle (pointer) to the expensive ones 
struct my_struct { 
    int simple; 
    struct expensive_handle * handle; 
}; 

struct expensive { 
    int content; // whatever 
}; 

बनाना एक my_struct अतिरिक्त सूचक बनाने चाहिए/अविवेक के लिए इस्तेमाल किया संभाल:

struct my_struct * new() { 
    struct my_struct * data = malloc(sizeof(*data)); 
    // Error handling please 
    // Set simple data members 
    data->handle = malloc(sizeof(*(data->handle))); 
    // Error handling please 
    data->handle->target = NULL; 
    return data; 
} 

+3

सी – DyZ

+1

में कोई 'म्यूटेबल' या उसके करीब कुछ भी नहीं है हां, 'const' को हटाने या यूबी पीड़ित करने की आवश्यकता है। हालांकि अच्छा पोस्ट। एक अच्छा जवाब सी spec उद्धृत करेगा। – chux

+0

कोड को 'my_get_expensive (const struct my_struct * s) में' const' की आवश्यकता क्यों है? शायद वह लक्ष्य किसी अन्य तरीके से संतुष्ट हो सकता है? – chux

उत्तर

2

आप (1) अपने कोड पुनर्गठन और अविवेक की एक परत जोड़ सकते हैं target सदस्य (जो गणना के बाद महंगे डेटा को इंगित करेगा) प्रारंभ में NULL पर सेट किया गया है।

प्रवेश (और इस प्रकार संभवतः आलसी गणना) महंगा डेटा सदस्यों तब क्योंकि उस my_struct का कोई डेटा सदस्य बदल गया है, यहां तक ​​कि एक const योग्य my_struct के साथ संभव है:

int get_expensive(struct my_struct const * ptr) { 
    if (ptr->handle->target == NULL) { 
    ptr->handle->target = malloc(sizeof(struct expensive)); 
    // Error handling please 
    puts("A hell of a computation just happened!"); 
    ptr->handle->target->content = 42; // WOO 
    } 
    return ptr->handle->target->content; 
} 

केवल बात यह है कि बदल जाता है *(ptr->handle) का डेटा सदस्य, struct expensive_handle। जो योग्य नहीं है (केवल handle नामक सूचक है)।

टेस्ट (Live on ideone):

int main(void) { 
    struct my_struct * p = new(); 
    printf("%d\n", get_expensive(p)); 
    printf("%d\n", get_expensive(p)); 
} 

(1) क्या यह उचित है या संसाधनों की एक पूरी अपशिष्ट (दोनों प्रोग्रामर और अभिकलन) अपने डमी उदाहरण से तय नहीं किया जा सकता है, हालांकि।

+0

मतदाता नीचे प्रिय, कृपया बताएं कि मेरे उत्तर के कौन से हिस्सों में सुधार किया जाना चाहिए। –

+0

धन्यवाद - संकेत मेरे निश्चित रूप से इसके लायक है (वास्तविक ...) मामले! – user422005

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