构造函数中调用虚函数
首先声明:我们永远不应该在构造函数和析构函数中调用虚函数:)
但是C#和C++对在构造函数中调用虚函数有不同的处理方法,先看例子:
C#:
class Parent
{
protected Parent()
{
Console.WriteLine("Parent ctor!");
Print();
}
protected virtual void Print()
{
Console.WriteLine("Parent print!");
}
}
class Child : Parent
{
private readonly int childField;
public Child()
{
childField = 10;
Console.WriteLine("Child ctor! " + childField);
}
protected override void Print()
{
Console.WriteLine("Child print! " + childField);
}
}
class Program
{
static void Main(string[] args)
{
Child sm = new Child();
}
}
C++:
using namespace std;
class Parent
{
public:
Parent()
{
cout<<"Parent ctor!"<<endl;
Print();
}
virtual ~Parent(){};
virtual void Print()
{
cout<<"Parent print!"<<endl;
}
};
class Child:public Parent
{
public:
Child()
{
childField = 10;
cout<<"Child ctor! "<<childField<<endl;
}
~Child(){};
void Print()
{
cout<<"Child print! "<<childField<<endl;
}
private:
int childField;
};
int _tmain(int argc, _TCHAR* argv[])
{
Child s;
return 0;
}
上述代码在VS11下的输出分别是:
C#:
Parent ctor!
Child print! 0
Child ctor! 10
C++:
Parent ctor!
Parent print!
Child ctor! 10
从这里我们可以看出对于C#,多态是保证的,但是因为base class的构造函数在sub class的构造函数之前调用,这个时候sub class的成员变量只是被初始化成了defau值,因此如果虚函数中使用了依赖于sub class的构造函数的东西,就会出错。
C++则相当于直接把virtual去掉了。
但是C#和C++对在构造函数中调用虚函数有不同的处理方法,先看例子:
C#:
class Parent
{
protected Parent()
{
Console.WriteLine("Parent ctor!");
Print();
}
protected virtual void Print()
{
Console.WriteLine("Parent print!");
}
}
class Child : Parent
{
private readonly int childField;
public Child()
{
childField = 10;
Console.WriteLine("Child ctor! " + childField);
}
protected override void Print()
{
Console.WriteLine("Child print! " + childField);
}
}
class Program
{
static void Main(string[] args)
{
Child sm = new Child();
}
}
C++:
using namespace std;
class Parent
{
public:
Parent()
{
cout<<"Parent ctor!"<<endl;
Print();
}
virtual ~Parent(){};
virtual void Print()
{
cout<<"Parent print!"<<endl;
}
};
class Child:public Parent
{
public:
Child()
{
childField = 10;
cout<<"Child ctor! "<<childField<<endl;
}
~Child(){};
void Print()
{
cout<<"Child print! "<<childField<<endl;
}
private:
int childField;
};
int _tmain(int argc, _TCHAR* argv[])
{
Child s;
return 0;
}
上述代码在VS11下的输出分别是:
C#:
Parent ctor!
Child print! 0
Child ctor! 10
C++:
Parent ctor!
Parent print!
Child ctor! 10
从这里我们可以看出对于C#,多态是保证的,但是因为base class的构造函数在sub class的构造函数之前调用,这个时候sub class的成员变量只是被初始化成了defau值,因此如果虚函数中使用了依赖于sub class的构造函数的东西,就会出错。
C++则相当于直接把virtual去掉了。