2014-09-23 14 views
6

header.hNghị quyết của chức năng ảo với các thông số mặc định

#include <iostream> 
using namespace std; 
class A 
{ 
    public: 
     virtual void display(int i=5) { cout<< "Base::" << i << endl; } 
}; 

class B : public A 
{ 
    public: 
     void display(int i=9) { cout<< "Derived::" << i << endl; } 
}; 

source.h

#include <iostream> 
#include "header.h" 
using namespace std; 
int main() 
{ 
    A * a = new B(); 
    a->display(); 

    A* aa = new A(); 
    aa->display(); 

    B* bb = new B(); 
    bb->display(); 
} 

đầu ra

Derived::5 
Base::5 
Derived::9 

hiểu biết của tôi là các hàm tham số mặc định đã được giải quyết trong suốt thời gian biên dịch bằng cách sử dụng quá tải hàm. Các hàm ảo sau đó được giải quyết trong suốt thời gian chạy bằng cách sử dụng chức năng ghi đè.

Nhưng những gì đang xảy ra là một mớ hỗn độn.
Độ phân giải chức năng thực sự xảy ra ở đây như thế nào?

+1

'độ phân giải lý luận mặc định được dựa trên loại tĩnh của đối tượng thông qua đó bạn gọi function' (ví dụ: dựa trên loại con trỏ). http://social.msdn.microsoft.com/Forums/en-US/90b9b8ee-ed5f-4ba8-93b5-612c4d906124/default-argument-and-inheritance-hierarchy –

+0

Lưu ý rằng bạn có thể giải quyết vấn đề này bằng cách quá tải ảo chức năng với một hàm ảo khác mà không có tham số, mà "chuyển tiếp" tới một tham số có tham số.Giống như: trong Base 'virtual void display() {display (9); } 'và trong Derived' void display() {display (5); } ' – leemes

Trả lời

7

Mã của bạn đang thực sự nhìn thấy bởi trình biên dịch như thế này:
(Phương pháp display() không phải là thực sự ở đó, nhưng các công trình giải quyết theo cách tương tự)

class A 
{ 
public: 
    virtual void display(int i) { cout<< "Base::" << i << endl; } 
    void display() { display(5); } 
}; 

class B : public A 
{ 
public: 
    void display(int i) override { cout<< "Derived::" << i << endl; } 
    void display() { display(9); } 
}; 

Bây giờ bạn nên hiểu điều gì xảy ra. Bạn đang gọi số gọi số số không ảo display() gọi hàm ảo. Nói cách nghiêm ngặt hơn: đối số mặc định được giải quyết giống như nếu phương thức không-arg không ảo có ở đó - theo loại biến (không phải kiểu thực tế của đối tượng), nhưng mã được thực thi theo để loại đối tượng thực, bởi vì nó là phương pháp ảo:

int main() 
{ 
    A * a = new B(); // type of a is A* real type is B 
    a->display(); // calls A::display() which calls B::display(5) 

    A* aa = new A(); // type of aa is A* real type is A 
    aa->display(); // calls A::display() which calls A::display(5) 

    B* bb = new B(); // type of bb is B* real type is B 
    bb->display(); // calls B::display() which calls B::display(9) 
} 
+0

Ồ, đây chính là điều tôi đang tìm kiếm.Hey, nhưng sau đó làm thế nào là 'Derived :: 5' in? Nó sẽ là 'Base :: 5' – cppcoder

+0

Khi bạn gọi' a-> display(); 'trên một đối tượng của kiểu (động)' B', nó gọi 'display();', đó là ** non- quá tải ảo ** 'display()' gọi 'hiển thị (5);' mà sau đó ** hầu như ** được giải quyết thành 'B :: display (5)'. Và trong đoạn mã gốc, một cái gì đó tương tự cũng xảy ra. Thay vì hàm phi ảo bổ sung, nó là tham số mặc định được giải quyết trên ** loại tĩnh **. – leemes

+1

Hmm, điều này phức tạp. – cppcoder

7

Không có đa hình trên đối số mặc định. Chúng được giải quyết thời gian biên dịch.

A::display có đối số mặc định bằng 5. B::display có đối số mặc định bằng 9. Nó chỉ loại a, aa, bb biến có vấn đề.

Việc sử dụng các đối số mặc định khác nhau trong các phương pháp đa hình gây nhầm lẫn và cần tránh.

+0

Tôi xin lỗi nhưng tôi không hiểu: tại sao' a-> display() 'hiển thị' Derived :: 5' và 'bb-> display()' đang hiển thị 'Derived :: 9'? Chúng được định nghĩa chính xác theo cùng một cách ... –

+2

@StefanoF Vì 'a' là kiểu' A * 'trong khi' bb' thuộc kiểu 'B *'. Do đó, 'a-> display()' sử dụng khai báo từ 'lớp A' trong khi' bb-> ​​display() 'sử dụng một từ' lớp B' –

5

hành vi này được quy định tại Chương 8.3.6: Mặc định lập luận trong Programming languages — C++ (ISO/IEC 14882:2003(E)):

Một cuộc gọi chức năng ảo (10,3) sử dụng mặc định argume nts trong khai báo của hàm ảo xác định bởi các loại tĩnh của con trỏ hoặc tham chiếu biểu thị các đối tượng

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