摘要:虛擬函數與建構子
當一個基礎類別呼叫了一個虛擬函數在不同與語言(C++/C#/Java)中會發生什麼事?
Java會執行衍生類別的虛擬函數,C#必須在衍生類別的覆寫函數中宣告時加入override識別子,
C++無解?(參考C++程式碼最後所列參考資料) 因此在做不同程式語言的程式碼轉換時必須注意此問題
-----C++ code------
#include <iostream>
using namespace std;
class base{
public:
base()
{
cout<<"base default construction"<<endl;
setmethod();
}
virtual void setmethod()
{
cout<<"base setmethod"<<endl;
callmethod();
}
virtual void callmethod()
{
cout<<"base callmethod"<<endl;
}
};
class child : public base{
public:
child()
{
cout<<"child construction"<<endl;
}
void setmethod()
{
cout<<"child setmethod"<<endl;
callmethod();
}
void callmethod()
{
cout<<"child callmethod"<<endl;
}
};
int main()
{
child *test = new child();
int x;
cin>>x;
}
/*
Ref:http://www.cis.nctu.edu.tw/chinese/doc/research/c++/C++FAQ-Chinese/c-cppfaq-2.html
Q66:若基底類別的建構子呼叫一個虛擬函數,為什麼衍生類別覆蓋掉的那個虛擬函
數卻不會被呼叫到?
在基底類別 Base 的建構子執行過程中,該物件還不是屬於衍生 Derived 的,所以
如果 "Base::Base()" 呼叫了虛擬函數 "virt()",則 "Base::virt()" 會被呼叫,
即使真的有 "Derived::virt()"。
類似的道理,當 Base 的解構子執行時,該物件不再是個 Derived 了,所以當
Base::~Base() 呼叫 "virt()",則 "Base::virt()" 會被執行,而非覆蓋後的版本
"Derived::virt()"。
當你想像到:如果 "Derived::virt()" 碰得到 Derived 類別的物件成員,會造成什
麼樣的災難,你很快就會看出這規則的明智之處。
*/
------C# code-------------
namespace Ineritance_CSharp
{
public class basec{
public basec()
{
System.Console.WriteLine("base construction");
setmethod();
}
public virtual void setmethod()
{
System.Console.WriteLine("base setmethod");
callmethod();
}
public virtual void callmethod()
{
System.Console.WriteLine("base callmethod");
}
}
public class child : basec
{
public child()
{
System.Console.WriteLine("child construction");
}
public override void setmethod()
{
System.Console.WriteLine("child setmethod");
callmethod();
}
public override void callmethod()
{
System.Console.WriteLine("child callmethod");
}
}
public class child1 : basec
{
public child1()
{
System.Console.WriteLine("child construction");
}
public void setmethod()
{
System.Console.WriteLine("child setmethod");
callmethod();
}
public void callmethod()
{
System.Console.WriteLine("child callmethod");
}
}
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("---child override method---");
child test = new child();
System.Console.WriteLine("----------------------");
System.Console.WriteLine("child non-override method");
child1 test1 = new child1();
System.Console.ReadLine();
}
}
}
--------Java code-----
class basec{
public basec()
{
System.out.println("base construction");
setmethod();
}
public void setmethod()
{
System.out.println("base setmethod");
callmethod();
}
public void callmethod()
{
System.out.println("base callmethod");
}
}
class child extends basec
{
public child()
{
System.out.println("child construction");
}
public void setmethod()
{
System.out.println("child setmethod");
callmethod();
}
public void callmethod()
{
System.out.println("child callmethod");
}
}
public class Inheritance_Java
{
public static void main(String[] args)
{
//System.out.println("---child override method---");
child test = new child();
/*
System.out.println("----------------------");
System.out.println("child non-override method");
child1 test1 = new child1();*/
}
}
--
Yotrew.Wing.蛋型.水瓶.U103.Che.KUAS
Yotrew.Wing.M98111XX@MS98.EDU/MIS.CSU
Yotrew.Wing.69241XX@MS92.CS.CCU
Yotrew.Wing.584012XX@89乙.Che.KUAS
Yotrew.Wing.b8803XXX@U92A.CSIE.ISU