2015-10-21 19 views
5

Tôi muốn lưu trữ thông qua hàm tạo của lớp là con trỏ tới đối tượng của một lớp khác. Cách chính xác để làm điều đó là gì?chuyển đổi không hợp lệ từ ‘const type *’ thành ‘type *’

Nếu tôi thay thế MyClass1* ptr bằng const MyClass1* ptr không có lỗi, nhưng trong trường hợp này tôi nghĩ rằng tôi không thể thay đổi ptr nữa. Cách chính xác để đạt được những gì tôi muốn là gì?

example.cpp

class MyClass1{ 
    public: 
     int a; 
     int b; 
}; 

class MyClass2{ 
    MyClass1* ptr; 
    public: 
     MyClass2(const MyClass1& obj){ptr = &obj;}; 
}; 

int main(int argc, char* argv[]){ 
    MyClass1 object1; 
    object1.a = object1.b = 0; 
    MyClass2 object2(object1); 

    return 0; 
} 

Biên dịch nó qua g++ -o example example.cpp cho tôi lỗi này

example.cpp: In constructor ‘MyClass2::MyClass2(const MyClass1&)’:

example.cpp:10:37: error: invalid conversion from ‘const MyClass1*’ to ‘MyClass1*’ [-fpermissive]

MyClass2(const MyClass1& obj){ptr = &obj;};

+3

Bản sao có thể có của [Sự khác biệt giữa const int \ *, const int \ * const và int const \ *?] (Http://stackoverflow.com/questions/1143262/what-is-the-difference là gì -between-const-int-const-int-const-và-int-const) –

+0

Tại sao bạn không loại bỏ 'const' bổ nghĩa của đối số' obj' của bạn? Ngoài ra bạn có thể trực tiếp vượt qua con trỏ thay vì tham chiếu. – aslg

+0

@aslg: vì tôi không muốn rằng hàm tạo có thể sửa đổi đối tượng. (tôi biết rằng không có gì thay đổi thực tế đối tượng đó) – giusva

Trả lời

2

Nếu bạn muốn thay đổi điều đó ptr điểm đến, sau đó chức năng của bạn cần phải lấy đối số của nó bằng không tham chiếu const (kể từ MyClass2 có thể sửa đổi):

MyClass2(MyClass1& obj) { ptr = &obj; } 

Hoặc, nếu bạn không có ý định thay đổi điều mà ptr điểm đến, sau đó ptr nên được khai báo là một con trỏ-to- const:

const MyClass1* ptr; 

Cả hai giải pháp sẽ gây ra các mã để biên dịch .

+0

'const MyClass1 &' không an toàn vì tạm thời có thể được chuyển vào – CoffeeandCode

+1

Nó cũng không an toàn vì một đối tượng không tạm thời có tuổi thọ ngắn hơn đối tượng 'Class2' có thể được chuyển vào. Nói chung, lưu trữ các tham chiếu không sở hữu/con trỏ dài thời gian là yêu cầu cho sự cố, vì những vấn đề đời. – emlai

+0

@zenith: trong thuật toán của tôi, đối tượng 'Class1' có tuổi thọ lâu hơn là đối tượng của' Class2' có con trỏ đến đối tượng đầu tiên. Tuy nhiên điều này rõ ràng là không đúng sự thật nói chung. Làm thế nào tôi có thể tính đến sự xuất hiện này? – giusva

0

Trước tiên hãy xóa phần bổ sung;

MyClass2(const MyClass1& obj){ptr = &obj;} 

không thể vượt qua đối const chức năng bên trong (có thể thay đổi nó sau này), vì vậy điều này có thể làm việc:

MyClass2(MyClass1 & obj){ 
    ptr = &obj; 
} 

nhưng ở đây giá trị của & obj thoát phạm vi địa phương.

2

Trả lời dựa trên một vài nhận xét cuối cùng.

tôi sẽ cung cấp cho bạn một ví dụ về const áp dụng cho con trỏ với ints,

int a = 2; 
int b = 3; 

int*    p1 = &a; // Modifiable pointer modifiable value 
const int*  p2 = &a; // Modifiable pointer const value 
int* const  p3 = &a; // Const pointer  modifiable value 
const int * const p4 = &a; // Const pointer  const value 

*p1 = 3; // Ok, modifiable left-value 
*p2 = 4; // Error: non-modifiable left-value 
*p3 = 5; // Ok 
*p4 = 6; // Error 

p1 = &b; // Ok: modifiable pointer 
p2 = &b; // Ok 
p3 = &b; // Error 
p4 = &b; // Error 

Trong trường hợp của bạn, bạn đang tìm kiếm một con trỏ sửa đổi nhưng giá trị const. Vì vậy, bạn muốn trường hợp thứ hai,

const MyClass1* ptr; 

(Đó là những gì bạn ban đầu có)

Có vẻ như bạn không thực sự cố gắng để thay đổi con trỏ?

2

Tôi biết từ nhận xét rằng bạn muốn sửa đổi nội dung của con trỏ, không phải con trỏ đối tượng trỏ đến, vì vậy hãy khai báo con trỏ ptrconst MyClass1* ptr. Điều này có nghĩa là ptr là một con trỏ tham chiếu đến một số const MyClass1. Vì vậy, bạn có thể thay đổi con trỏ, nhưng bạn không thể sửa đổi đối tượng được tham chiếu bởi con trỏ.

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