เสมือนอาจมีค่าเริ่มต้น ค่าเริ่มต้นในชั้นฐานไม่ได้รับการสืบทอดโดยชั้นเรียนที่ได้รับ
ใช้ค่าเริ่มต้นใด - เช่นคลาสพื้นฐาน 'หรือคลาสที่ได้รับ' - จะถูกกำหนดโดยประเภทสแตติกที่ใช้ในการเรียกใช้ฟังก์ชัน ถ้าคุณเรียกใช้ผ่านวัตถุคลาสพื้นฐานตัวชี้หรือการอ้างอิงจะใช้การแทนค่าเริ่มต้นในคลาสพื้นฐาน ในทางกลับกันถ้าคุณเรียกใช้คลาสวัตถุที่ได้รับตัวชี้หรือการอ้างอิงค่าเริ่มต้นที่แสดงในคลาสที่ได้รับจะถูกใช้ มีตัวอย่างด้านล่างใบเสนอราคามาตรฐานที่แสดงให้เห็นนี้
คอมไพเลอร์บางคนอาจทำสิ่งที่แตกต่างกัน แต่นี่คือสิ่งที่มาตรฐาน C ++ 03 และ C ++ 11 พูดว่า:
8.3.6.10:
การเรียกฟังก์ชันเสมือน (10.3) ใช้อาร์กิวเมนต์เริ่มต้นในการประกาศฟังก์ชันเสมือนที่กำหนดโดยชนิดคงที่ของตัวชี้หรือการอ้างอิงที่แสดงถึงวัตถุ ฟังก์ชั่นการแทนที่ในคลาสที่ได้รับไม่ได้รับการขัดแย้งเริ่มต้นจากฟังก์ชั่นมันแทนที่ ตัวอย่าง:
struct A {
virtual void f(int a = 7);
};
struct B : public A {
void f(int a);
};
void m()
{
B* pb = new B;
A* pa = pb;
pa->f(); //OK, calls pa->B::f(7)
pb->f(); //error: wrong number of arguments for B::f()
}
นี่คือตัวอย่างโปรแกรมที่แสดงให้เห็นว่ามีการเลือกค่าเริ่มต้นเป็นอย่างไร ฉันใช้struct
s ที่นี่มากกว่าclass
es เพียงเพื่อความกะทัดรัด - class
และstruct
เหมือนกันทุกประการยกเว้นทัศนวิสัยเริ่มต้น
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
using std::stringstream;
using std::string;
using std::cout;
using std::endl;
struct Base { virtual string Speak(int n = 42); };
struct Der : public Base { string Speak(int n = 84); };
string Base::Speak(int n)
{
stringstream ss;
ss << "Base " << n;
return ss.str();
}
string Der::Speak(int n)
{
stringstream ss;
ss << "Der " << n;
return ss.str();
}
int main()
{
Base b1;
Der d1;
Base *pb1 = &b1, *pb2 = &d1;
Der *pd1 = &d1;
cout << pb1->Speak() << "\n" // Base 42
<< pb2->Speak() << "\n" // Der 42
<< pd1->Speak() << "\n" // Der 84
<< endl;
}
ผลลัพธ์ของโปรแกรมนี้ (บน MSVC10 และ GCC 4.4) คือ:
Base 42
Der 42
Der 84