2011-11-02 20 views
23

Người phỏng vấn cho tôi xem một mã như thế này và hỏi tôi có nên biên dịch hay không và đưa ra lý do của tôi. Tôi nói với anh ta rất chắc chắn rằng nó sẽ không biên dịch, bởi vì 10 là hằng số và bạn không thể gán hằng số cho tham chiếu không const (như int & b = 10 sẽ không biên dịch), cũng là _a là biến tạm thời và nó là cũng được coi là const, một lần nữa, bạn không thể sử dụng tham chiếu không const để tham chiếu biến const.Tại sao tính toán này? Mong đợi "không thể chỉ định hằng số cho tham chiếu không const"

Tuy nhiên, sau khi tôi trở về nhà với sự ngạc nhiên của mình, tôi thấy nó biên dịch hoàn hảo với tất cả các trình biên dịch có thể. Ngoài ra, tôi đã không nhận được công việc. Phần nào của sự hiểu biết của tôi đã đi sai?

class A { 
    int& a; 
public: 
    A(int _a):a(_a) {} 
}; 

int main() { 
    A a(10); 
}  
+24

Vị trí bạn đang phỏng vấn là gì? Nếu nó là bất cứ điều gì khác hơn là xây dựng một trình phân tích cú pháp C++, tôi muốn nói rằng nó có thể vô lý để cần phải biết từng góc tối nghĩa của C++ như thế này. – Mysticial

+11

Tôi có ấn tượng rằng những người phỏng vấn nhấn mạnh quá nhiều vào việc biết các góc tối nghĩa của ngôn ngữ và không đủ về kỹ năng thiết kế và thực hành tốt nhất. –

+1

@Mysticial: đây là một lỗ hổng phổ biến cho các nhà phát triển mới vì mã này dường như sẽ hoạt động lúc đầu nhưng sẽ không thành công tại một điểm ngẫu nhiên (sau một cuộc gọi hàm). – Dani

Trả lời

27

không có "nhiệm vụ" của một const với mã này ...

Mã gọi các nhà xây dựng mà phải mất một int và lần lượt gọi initializer của int&. Bạn bỏ qua một vài bước trình biên dịch thấy/mất khi bạn giả định nó có nghĩa là int& b = 10 trong khi nó giống như _a = 10; int& a = _a;. nó biên dịch nhưng là không có gì bạn muốn sử dụng (ràng buộc một tham chiếu đến ngăn xếp mà sau này sẽ dẫn đến hành vi không xác định/tham nhũng) ...

7

Điều này sẽ liên kết với ngăn xếp, bởi vì đối số chức năng có thể bị ràng buộc bởi tài liệu tham khảo. điều này tuy nhiên không an toàn chút nào và sẽ gây ra hành vi không xác định và ngăn xếp tham nhũng tại một số điểm.

12

_a là một biến tạm thời và nó cũng được coi là const,

sai. Trong phạm vi của thân hàm khởi tạo và danh sách khởi tạo, nó không phải là tạm thời. Nó là một đối số giá trị và hàm số - nó kéo dài vượt quá mức sử dụng duy nhất của bạn cho toàn bộ cơ quan chức năng.

Ngoài ra, giá trị và const hoàn toàn không có gì để làm với nhau, ngoại trừ trong C++ 03 bạn không thể liên kết tham chiếu không const với giá trị. Bạn có thể, ví dụ, gọi rất nhiều chức năng không const trên rvalues ​​tốt.

Mã này là trực tiếp tương đương với

int main() { 
    int i = 10; 
    int& x = i; 
} 

Với những niềm vui thêm trong những vấn đề liên quan đến cuộc đời với nó là trong một lớp học.

4

Có 2 câu hỏi về câu hỏi này.

q1) có nên biên dịch hay không?

Trả lời: nó sẽ biên dịch vì ở đây đề cập đến _a, nó không phải là trình biên dịch nhức đầu như thế nào _a sẽ nhận dữ liệu.

q2) Mã có đúng không? Ý tôi là liệu sẽ có lỗi thời gian chạy hay không?

Trả lời: Đây không phải là mã đúng. Ở đây a đề cập đến _a là biến ngăn xếp. Vì vậy, nếu bạn acess tham chiếu biến một sử dụng lớp A đối tượng, sản lượng sẽ không thể đoán trước. Cho phép lấy ví dụ như được đưa ra bên dưới:

class A { 
public: 
    int& a; 

    A(int _a):a(_a) {} 
}; 

int main() { 
    A a(10); 
    A a1(11); 
    cout << a.a; 
}  

Xem kết quả.Đầu ra là không thể đoán trước vì bạn đang cố gắng truy cập biến tham chiếu, biến này đề cập đến biến ngăn xếp của hàm tạo

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