2010-07-04 47 views
8

Làm cách nào để buộc const-ness của bộ nhớ được trỏ tới bởi obj-> val1 trong hàm fn?C/C++: Con trỏ trong cấu trúc Const

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

Mã ở đây khá tự giải thích. Tôi cần để có thể tạo một đối tượng không phải là const và điền nó với dữ liệu, nhưng sau đó chuyển nó vào một hàm mà dữ liệu này không thể sửa đổi được. Làm thế nào tôi có thể đi về điều này?

Tôi biết tôi chỉ có thể vượt qua trong một con trỏ const int, nhưng về mặt lý thuyết, lớp này có chứa một số con trỏ khác mà tôi sẽ cần trong "fn" là tốt.

Cảm ơn,

Griff

Trả lời

6

Vì bạn được gắn thẻ như C++, bạn có thể làm cho các thành viên private và thực hiện một accessor trả về một const int *. Ban đầu bạn có thể đặt thành viên thông qua hàm tạo của bạn hoặc hàm friend.

+0

Ahh. Tôi quên rằng các cấu trúc trong C++ có thể có các phương thức và các biến thành viên. Điều đó sẽ giải quyết vấn đề của tôi, mặc dù chỉ cho cười khúc khích, là nó có thể ở tất cả để làm điều này trong C? – Griffin

+0

@Griffin: Nếu bạn thực sự muốn chắc chắn rằng bạn có thể truyền nó một cách riêng biệt. –

+0

@Griffin: vâng. Xem câu trả lời của tôi, có giá trị cho cả C và C++. –

2

Bạn thực sự không thể. Một hàm foo chỉ rõ rằng các thành viên bên trong là const, nghĩa là chúng là các con trỏ liên tục đến các số nguyên, không phải là các con trỏ tới các số nguyên không đổi.

Giải pháp thích hợp cho việc này là thông qua đóng gói, ẩn các thành viên này và cung cấp giao diện công khai. Một giải pháp thực tế, bạn nên cấm sửa đổi foo struct, sẽ được thông qua thừa kế riêng:

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

Tất nhiên, bạn sẽ cần phải tạo các nhà thầu phù hợp, vv, để foo ban đầu có thể được thiết lập lên.

+0

Dường như tôi sẽ phải thêm một số phức tạp thêm vào cấu trúc nhỏ bé nghèo nàn của tôi. Cảm ơn các mẫu mã thông tin! – Griffin

4

Tôi không phải là C++ người, nhưng trong C, tôi muốn xử lý này thông qua hai tuyên bố struct khác nhau, một cộng đồng, một tin:

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

Khi tôi cố gắng biên dịch trên w/GCC , Tôi nhận được các lỗi trình biên dịch sau, vì tôi đang cố sửa đổi bộ nhớ chỉ đọc:

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 .. Bây giờ đó là thông minh. Kudos cho bạn, thưa bạn. Tôi đang thêm vào túi của tôi về thủ đoạn. – Griffin

Các vấn đề liên quan