2011-12-03 46 views
6

Tôi đã tìm thấy một hành vi lạ khi sử dụng biến tham chiếu.Biến tham chiếu và chức năng ảo

Đây là triển khai lớp:

class Base { 
    public: 
     virtual void Method() = 0; 
}; 

class DerivedA : public Base { 
    public: 
     virtual void Method() {} 
} 

class DerivedB : public Base { 
    public: 
     virtual void Method() {} 
} 

Dưới đây là một ví dụ mã mà có hành vi lạ:

void main(int argc, char *argv[]) { 
    DerivedA a; 
    DerivedB b; 
    Base &base = a; 

    base.Method(); // Calls DerivedA::Method 

    base = b; 
    base.Method(); // Calls DerivedA::Method!!! Why doesn't call DerivedB.Method()? 
} 

Tóm lại, có vẻ như chức năng ảo bảng con trỏ "liên quan" đến biến tham chiếu chỉ xác định khi khởi tạo biến tham chiếu. Nếu tôi gán lại biến tham chiếu, vfpt sẽ không thay đổi.

Điều gì xảy ra ở đây?

Trả lời

13

Base &base là một tài liệu tham khảo, ví dụ: bí danh cho các đối tượng a, vì vậy việc giao base = b tương đương với a = b, mà rời khỏi base thingie vẫn cùng một đối tượng của lớp tương tự. Nó không phải là một sự tái chỉ định của con trỏ như bạn dường như giả định.

+5

Tôi nghĩ câu trả lời này xứng đáng được đánh dấu màu xanh lá cây! – Walter

+2

Vâng, tôi nghĩ rằng đây sẽ là câu trả lời được chấp nhận. – Rafid

+0

Cảm ơn, mặc dù câu trả lời được chấp nhận là một trong những người hỏi đã chấp nhận và nó là okay rằng ông chấp nhận câu trả lời khác ;-) –

7

Tài liệu tham khảo chỉ có thể được khởi tạo một lần. Bạn không thể gán một đối tượng mới cho một tham chiếu. Điều thực sự xảy ra ở đây là toán tử = của Base được gọi và đối tượng bên dưới vẫn là DerivedA chứ không phải DerivedB.

+2

Mỗi ngày luôn luôn có một cái gì đó để tìm hiểu. – Luca

+0

Tôi không chắc chắn điều này có đúng không. Toán tử = không được định nghĩa trong Base, vì vậy không có gì để gọi thực sự, ngoài việc thực thi mặc định của C++ =. Tôi nghĩ những gì đang xảy ra ở đây là những gì @MichaelKrelin trả lời dưới đây. – Rafid

+0

@Rafid Như bạn đã viết, có thực thi mặc định toán tử =. Việc thực hiện mặc định không phải là ảo và kiểu cơ sở là Base vì vậy Base :: operator =() được gọi. Câu trả lời của Michael cũng đúng. Hai câu trả lời không mâu thuẫn lẫn nhau. – selalerer

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