Virtuals haben möglicherweise Standardeinstellungen. Die Standardeinstellungen in der Basisklasse werden nicht von abgeleiteten Klassen geerbt.
Welche Standardeinstellung verwendet wird, dh die Basisklasse 'oder eine abgeleitete Klasse', wird durch den statischen Typ bestimmt, der zum Aufrufen der Funktion verwendet wird. Wenn Sie ein Basisklassenobjekt, einen Zeiger oder eine Referenz aufrufen, wird der in der Basisklasse angegebene Standard verwendet. Wenn Sie dagegen ein abgeleitetes Klassenobjekt, einen Zeiger oder eine Referenz aufrufen, werden die in der abgeleiteten Klasse angegebenen Standardwerte verwendet. Unter dem Standardzitat befindet sich ein Beispiel, das dies demonstriert.
Einige Compiler machen möglicherweise etwas anderes, aber dies ist, was die C ++ 03- und C ++ 11-Standards sagen:
8.3.6.10:
Ein virtueller Funktionsaufruf (10.3) verwendet die Standardargumente in der Deklaration der virtuellen Funktion, die durch den statischen Typ des Zeigers oder der Referenz bestimmt wird, die das Objekt bezeichnen. Eine überschreibende Funktion in einer abgeleiteten Klasse erhält keine Standardargumente von der Funktion, die sie überschreibt. Beispiel:
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()
}
Hier ist ein Beispielprogramm, um zu demonstrieren, welche Standardeinstellungen übernommen wurden. Ich verwende struct
hier eher s als class
nur der Kürze halber - class
und bin struct
in fast jeder Hinsicht genau gleich, mit Ausnahme der Standardsichtbarkeit.
#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;
}
Die Ausgabe dieses Programms (unter MSVC10 und GCC 4.4) lautet:
Base 42
Der 42
Der 84