Im Moment lerne ich die Funktionen der Vererbung in C++ und wollte das kürzlich erlernte Konzept der Virtual Base-Klassen testen. Ich habe versucht, die folgenden einfachen Code:Warum verhält sich die Initialisierung in C++ 11 bei virtuellen Basisklassen merkwürdig?
#include <iostream>
using namespace std;
class A
{
private:
int m_value;
string m_caller;
public:
A(int p_value, string p_caller) : m_value{p_value}, m_caller{p_caller}
{
cout<<"Instantiating A via "<<m_caller<<endl;
}
};
class B : virtual public A
{
private:
int m_value;
public:
B(int p_value1,int p_value2) : A{p_value1,"B"}, m_value{p_value2}
{
cout<<"Instantiating B."<<endl;
}
};
class C : public B
{
public:
C(int p_value1,int p_value2) : A{p_value1,"C"}, B(p_value1, p_value2)
{
cout<<"Instantiating C."<<endl;
}
};
int main()
{
C c1(1,2);
return 0;
}
Bitte beachten Sie die B(p_value1, p_value2)
im Konstruktor der Klasse C. Dies gab mir die gewünschte Ausgabe:
Instantiating A via C
Instantiating B.
Instantiating C.
Aber der Moment, als ich es zu B{p_value1, p_value2}
geändert, ich habe die folgende Ausgabe:
Instantiating A via C
Instantiating A via B
Instantiating B.
Instantiating C.
ich habe versucht, für die Antwort suchen, aber alle Antworten, die ich habe einige C++ Standards zitiert . Als Anfänger in OOPs suche ich nach einer einfacheren Erklärung für dieses Verhalten. Vielen Dank!
P.S. Ich verwende C :: B in Windows mit Compiler g ++ 4.8.1.
Fyi, clang ++ 3.7 zeigt nicht das Verhalten, das Sie beschreiben. Beide Versionen geben die gleiche Ausgabe aus (die erste). – WhozCraig
Sie rufen den Kopierkonstruktor im zweiten Fall auf. – lorro
@UpAndAdam Die am weitesten abgeleitete Klasse ist verantwortlich für die Initialisierung von virtuellen Basisklassen, der Code würde nicht kompilieren, wenn das OP den Konstruktor von 'A' nicht direkt aufruft. Und was ist das mit * übergeben konvertierten String-Literale, als ob sie Ints * sind? – Praetorian