2013-02-14 63 views
31

Tôi rất mới với C++ và đây là tình huống của tôi. Tôi có một tham chiếu đến MyOjbect, nhưng đối tượng chính xác tùy thuộc vào điều kiện. Vì vậy, tôi muốn làm một cái gì đó như thế này:Cách khai báo tham chiếu và khởi tạo sau

MyObject& ref; 
if([condition]) 
    ref = MyObject([something]) 
else 
    ref = MyObject([something else]); 

Tôi không thể làm điều này ngay bây giờ vì trình biên dịch không cho phép tôi khai báo nhưng không khởi tạo tham chiếu. Tôi có thể làm gì để đạt được mục tiêu của mình ở đây?

+2

Đó có phải là khởi tạo từ tạm thời không? Điều đó sẽ không hoạt động ngay cả khi không có điều kiện: 'MyObject & ref = MyObject ([something]);', bởi vì bạn không thể liên kết tạm thời với tham chiếu không phải lvalue. – GManNickG

+0

@GManNickG: điều này cũng áp dụng cho câu trả lời của Zaffy và suszterpatt? – qPCR4vir

+0

@ qPCR4vir: Yup. Câu hỏi vẫn đứng, theo một cách nào đó, không phải trực tiếp. – GManNickG

Trả lời

30

Bạn cần phải initliaze nó. Nhưng nếu bạn muốn khởi tạo điều kiện, bạn có thể làm điều gì đó như sau:

MyObject& ref = (condition) ? MyObject([something]) : MyObject([something else]); 
+2

Tôi không thể làm điều này bởi vì tôi thực sự làm công cụ bên trong những điều kiện đó. Tôi rất bối rối ở đây. Điều này trông giống như một kịch bản khá phổ biến đối với tôi tại sao nó không được phép? Kiểu mã hóa của tôi có chống C++ không? – user1861088

+3

@ user1861088: "Tôi không thể làm điều này bởi vì tôi thực sự làm công cụ bên trong những điều kiện" Vậy tại sao bạn không thực sự hiển thị những gì bạn đang cố gắng làm trong câu hỏi? – GManNickG

+0

điều tôi muốn nói là tôi thực thi nhiều dòng mã bên trong mỗi điều kiện thay vì chỉ gọi một hàm trả về một giá trị. Vì vậy, tôi không thể sử dụng? : đúng? – user1861088

9

Trong C++, bạn không thể khai báo tham chiếu mà không khởi tạo. Bạn phải khởi tạo nó.

+1

Tôi hiểu điều đó. Vì vậy, bất kỳ lời khuyên về một đi bộ xung quanh? Về cơ bản tôi cần tham chiếu ở phạm vi lớn hơn điều kiện. – user1861088

+0

@ user1861088 Trong trường hợp đó, hoặc là 1. thiết kế lại mã của bạn (ưa thích), 2. sử dụng một con trỏ (không ưa thích). –

+1

3. không sử dụng một tham chiếu, chỉ cần sử dụng một đối tượng –

8

Câu trả lời ngắn gọn: bạn thì không.

câu trả lời nhẹ còn: làm một cái gì đó như thế này:

MyObject& getObject() 
{ 
    if([condition]) 
     return [something] 
    else 
     return [something else]; 
} 

MyObject& ref = getObject(); 

kỹ khuyến cáo thông thường liên quan đến tài liệu tham khảo áp dụng tất nhiên.

+0

vâng tôi nghĩ về điều này nhưng .. nó chỉ là lạ mà tôi phải làm tất cả điều này để đạt được một mục tiêu dường như đơn giản :( – user1861088

+0

Tại sao 'getObject()' trả lại một tham chiếu? Nó đề cập đến những gì? –

+0

& Jonathan: nằm trong phần "tuyên bố từ chối trách nhiệm thông thường".) – suszterpatt

10

Bạn không thể thực hiện việc này. Tài liệu tham khảo phải được ràng buộc với một cái gì đó, bạn có thể không thích nó nhưng nó ngăn chặn một lớp toàn bộ các lỗi, bởi vì nếu bạn có một tham chiếu, bạn luôn có thể giả định nó bị ràng buộc với một cái gì đó, không giống như một con trỏ có thể là null.

Mã ví dụ của bạn sẽ không hoạt động vì bạn cố gắng liên kết tham chiếu không phải const với đối tượng tạm thời, không hợp lệ.

Tại sao bạn cần nó làm tham chiếu? Một giải pháp sẽ được đảm bảo loại của bạn có một constructor mặc định không tốn kém và có thể được di chuyển một cách hiệu quả, sau đó chỉ cần làm:

MyObject obj; 
if([condition]) 
    obj = MyObject([something]) 
else 
    obj = MyObject([something else]); 

Nếu không, bạn sẽ phải đặt mã có điều kiện trong một hoặc nhiều chức năng, một trong hai:

const MyObject& ref = createObject([condition]); 

hoặc

const MyObject& ref = [condition] ? doSomething() : doSomethingElse(); 

Lưu ý rằng cả hai phiên bản sử dụng một const tài liệu tham khảo, có thể liên kết với một tạm thời, nếu đối tượng phải không const, sau đó một lần nữa dừng lại cố gắng sử dụng một tài liệu tham khảo:

MyObject obj = createObject([condition]); 

này có lẽ sẽ giống như hiệu quả như những gì bạn đang cố gắng để làm, nhờ sự return value optimization

9

AFAIK này có thể' t được thực hiện với một tham chiếu. Bạn sẽ phải sử dụng con trỏ:

MyClass *ptr; 

if (condition) 
    ptr = &object; 
else 
    ptr = &other_object; 

Con trỏ sẽ hoạt động tương tự như tham chiếu. Chỉ cần đừng quên sử dụng -> để truy cập thành viên.

+1

Bạn chỉ có thể khai báo tham chiếu là 'MyClass & ref = * ptr' nếu bạn muốn biến nó thành tham chiếu ... – poizan42

+0

tuyên bố nó là con trỏ sẽ không giải quyết trường hợp rvalue là sự trả về hàm –

3
MyClass *ptr; 

if (condition) 
    ptr = &object; 
else 
    ptr = &other_object; 

MyClass &ref = *ptr; 
+2

Khi trả lời , hãy xem xét viết một lời giải thích về mã bạn đã viết và câu trả lời này bổ sung hoàn toàn không có gì mới cho câu hỏi * rất cũ. – Ajean

+1

Điều này trông rất giống với mã từ [câu trả lời này] (http://stackoverflow.com/a/14885051). –

+0

Trong khi thiếu bất kỳ lời giải thích nào là xấu, đây vẫn là câu trả lời thực sự duy nhất mà không giới thiệu bất cứ điều gì thêm hoặc giới hạn bạn với những gì có thể được viết trong một nhà điều hành ternary ... – poizan42

0

Bạn có thể sử dụng từ khóa "extern": lần đầu tiên (giả sử, trong tệp tiêu đề) bạn có thể khai báo biến trước đó với từ khóa "extern". Sau đó (trong tệp nguồn) bạn lặp lại khai báo mà không có "extern" và gán giá trị cho nó.

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