Đây là một ý tưởng tồi, bởi vì các đối số mặc định bạn nhận được sẽ phụ thuộc vào kiểu tĩnh của đối tượng, trong khi virtual
chức năng được gửi đến sẽ phụ thuộc vào loại động .
Điều đó có nghĩa là, khi bạn gọi một hàm với các đối số mặc định, các đối số mặc định được thay thế vào thời gian biên dịch, bất kể hàm đó có virtual
hay không.
@cppcoder đã đưa ra ví dụ sau trong câu hỏi [đã đóng] của mình :
struct A {
virtual void display(int i = 5) { std::cout << "Base::" << i << "\n"; }
};
struct B : public A {
virtual void display(int i = 9) override { std::cout << "Derived::" << i << "\n"; }
};
int main()
{
A * a = new B();
a->display();
A* aa = new A();
aa->display();
B* bb = new B();
bb->display();
}
Mà tạo ra đầu ra sau đây:
Derived::5
Base::5
Derived::9
Với sự trợ giúp của lời giải thích ở trên, thật dễ dàng để biết lý do tại sao. Tại thời gian biên dịch, trình biên dịch thay thế các đối số mặc định từ các hàm thành viên của các kiểu tĩnh của con trỏ, làm cho main
hàm tương đương như sau:
A * a = new B();
a->display(5);
A* aa = new A();
aa->display(5);
B* bb = new B();
bb->display(9);