C++/CLI的函数覆盖

时间:2021-04-04 22:30:23

隐式覆盖
指iso-c++的函数覆盖,不同的是必须在子类覆盖函数最后加上关键字override
如:

C++/CLI的函数覆盖virtual   void  Speak()  override
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {}

 

隐藏覆盖
表示子类与父类同名的函数不再覆盖相应父类函数,而是新建这个函数。即与父类没有多态关系。

C++/CLI的函数覆盖ref   class  ParentClass
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖 
virtual void Print();
C++/CLI的函数覆盖}

C++/CLI的函数覆盖
ref   class  ChildClass
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖 
virtual void Print() new;
C++/CLI的函数覆盖}

C++/CLI的函数覆盖ParentClass
^  pp  =  gcnew ChildClass;
C++/CLI的函数覆盖pp
-> Print();
C++/CLI的函数覆盖

调用的是父类的Print()。


显式覆盖

显式覆盖是C++/CLI的新特性,有如下3种性质:
1.可以覆盖不同名的父类函数

C++/CLI的函数覆盖ref   class  Puppy :  public  Dog
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖 
virtual void Yip () = Dog::Speak
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{
C++/CLI的函数覆盖 }

C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖

2.可以覆盖不是直接父类的函数

C++/CLI的函数覆盖ref   class  Animal
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖C++/CLI的函数覆盖 
virtual void Speak()...{};
C++/CLI的函数覆盖}

C++/CLI的函数覆盖
ref   class  Cat: public  Aniaml
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖C++/CLI的函数覆盖 
virtual void Speak()overrid...{};
C++/CLI的函数覆盖}

C++/CLI的函数覆盖
ref   class  Tiger :  public  Cat
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖 
virtual void Growl () = Animal::Speak
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{
C++/CLI的函数覆盖 }

C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖

3.可以覆盖两个以上的函数

C++/CLI的函数覆盖ref   class  Tiger :  public  Cat
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖 
virtual void Speak() override = Animal::Speak 
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{
C++/CLI的函数覆盖  Console::WriteLine(
"Tiger says Growl");
C++/CLI的函数覆盖 }

C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖

Tiger::Speak()的override关键字表示Tiger::Speak()覆盖新建的Cat::Speak(),
但是使用override必须保证覆盖函数和父类函数同名。
“=Animal::Speak”表示Tiger::Speak()还覆盖Animal::Speak()
也可以这样做:

C++/CLI的函数覆盖ref   class  Tiger :  public  Cat
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖 
virtual void Growl() = Animal::Speak, Cat::Speak
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{
C++/CLI的函数覆盖 Console::WriteLine(
"Tiger says Growl");
C++/CLI的函数覆盖 }

C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖

使用两个异名覆盖可以完成上述相同的功能,好处是无需和父类函数同名。


下面列出完整的测试代码:

C++/CLI的函数覆盖#include  " stdafx.h "
C++/CLI的函数覆盖
using   namespace  System;
C++/CLI的函数覆盖
C++/CLI的函数覆盖
ref   class  Animal
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖
virtual void Speak ()
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{Console::WriteLine("Animal is Mysteriously Silent");}
C++/CLI的函数覆盖
C++/CLI的函数覆盖
virtual void Eat()
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{Console::WriteLine("Animal is Eating");}
C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖
C++/CLI的函数覆盖
ref   class  Cat :  public  Animal
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖
virtual void Speak() override
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{Console::WriteLine("Cat says Meow");}
C++/CLI的函数覆盖
C++/CLI的函数覆盖
virtual void Eat() override
C++/CLI的函数覆盖C++/CLI的函数覆盖 
...{Console::WriteLine("Cat is Eating");}
C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖
C++/CLI的函数覆盖
ref   class  Tiger :  public  Cat
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖
public:
C++/CLI的函数覆盖
virtual void TigerEat()=Cat::Speak,Animal::Eat
C++/CLI的函数覆盖C++/CLI的函数覆盖    
...{Console::WriteLine("Tiger is Speaking and Eating");}
C++/CLI的函数覆盖
C++/CLI的函数覆盖
virtual void Speak() override
C++/CLI的函数覆盖C++/CLI的函数覆盖    
...{Console::WriteLine("Tiger says Grrrr");}
C++/CLI的函数覆盖}
;
C++/CLI的函数覆盖
C++/CLI的函数覆盖
void  main()
C++/CLI的函数覆盖C++/CLI的函数覆盖
... {
C++/CLI的函数覆盖    
// Array of Animal handles
C++/CLI的函数覆盖
    array<Animal^>^ animals = gcnew array<Animal^> 
C++/CLI的函数覆盖C++/CLI的函数覆盖    
...
C++/CLI的函数覆盖        gcnew Animal(), 
C++/CLI的函数覆盖        gcnew Cat(), 
C++/CLI的函数覆盖        gcnew Tiger() 
C++/CLI的函数覆盖   }
;
C++/CLI的函数覆盖
C++/CLI的函数覆盖    
for each ( Animal ^in animals)
C++/CLI的函数覆盖C++/CLI的函数覆盖    
...{
C++/CLI的函数覆盖        a
->Speak();
C++/CLI的函数覆盖    }

C++/CLI的函数覆盖    Console::WriteLine();
C++/CLI的函数覆盖
C++/CLI的函数覆盖    
for each ( Animal ^in animals)
C++/CLI的函数覆盖C++/CLI的函数覆盖    
...{
C++/CLI的函数覆盖        a
->Eat();
C++/CLI的函数覆盖    }

C++/CLI的函数覆盖
C++/CLI的函数覆盖 Tiger
^ dd = gcnew Tiger;
C++/CLI的函数覆盖 dd
->Speak();
C++/CLI的函数覆盖
C++/CLI的函数覆盖 Console::ReadLine();
C++/CLI的函数覆盖}

C++/CLI的函数覆盖
C++/CLI的函数覆盖

最后的结果
Animal is Mysteriously Silent
Cat says Meow
Tiger is Speaking and Eating

Animal is Eating
Cat is Eating
Tiger is Speaking and Eating
Tiger is Speaking and Eating

很奇怪,第三个输出是Tiger is Speaking and Eating,而不是Tiger says Grrrr。
Tiger类使用了两个异名覆盖:Animal::Speak,Animal::Eat。同时也覆盖了Cat的方法Speak。
但是调用时,调用了对Animal的覆盖,没有调用对Cat的覆盖。是不是对基类的覆盖优先呢。暂时可以这么理解吧。