C++/CLI的函数覆盖

本文介绍了C++/CLI中的函数覆盖概念,包括隐式覆盖和显式覆盖。隐式覆盖需在子类函数末尾添加`override`关键字,以确保与父类函数同名并实现多态。显式覆盖则是C++/CLI的新特性,允许覆盖不同名的父类函数、不是直接父类的函数以及两个以上函数。通过代码示例展示了如何进行函数覆盖,并指出在使用多个异名覆盖时可能出现的调用行为,即优先调用对基类的覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

virtual void Speak() override
{}

 

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

ref class ParentClass
{
 
virtual void Print();
}

ref class ChildClass
{
 
virtual void Print() new;
}

ParentClass
^ pp = gcnew ChildClass;
pp
->Print();

调用的是父类的Print()。


显式覆盖

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

ref class Puppy : public Dog
{
public:
 
virtual void Yip () = Dog::Speak
 
{
 }

}
;

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

ref class Animal
{
 
virtual void Speak(){};
}

ref class Cat:public Aniaml
{
 
virtual void Speak()overrid{};
}

ref class Tiger : public Cat
{
public:
 
virtual void Growl () = Animal::Speak
 
{
 }

}
;

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

ref class Tiger : public Cat
{
public:
 
virtual void Speak() override = Animal::Speak 
 
{
  Console::WriteLine(
"Tiger says Growl");
 }

}
;

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

ref class Tiger : public Cat
{
public:
 
virtual void Growl() = Animal::Speak, Cat::Speak
 
{
 Console::WriteLine(
"Tiger says Growl");
 }

}
;

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


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

#include "stdafx.h"
using namespace System;

ref class Animal
{
public:
virtual void Speak ()
 
{Console::WriteLine("Animal is Mysteriously Silent");}

virtual void Eat()
 
{Console::WriteLine("Animal is Eating");}
}
;

ref class Cat : public Animal
{
public:
virtual void Speak() override
 
{Console::WriteLine("Cat says Meow");}

virtual void Eat() override
 
{Console::WriteLine("Cat is Eating");}
}
;

ref class Tiger : public Cat
{
public:
virtual void TigerEat()=Cat::Speak,Animal::Eat
    
{Console::WriteLine("Tiger is Speaking and Eating");}

virtual void Speak() override
    
{Console::WriteLine("Tiger says Grrrr");}
}
;

void main()
{
    
// Array of Animal handles
    array<Animal^>^ animals = gcnew array<Animal^> 
    

        gcnew Animal(), 
        gcnew Cat(), 
        gcnew Tiger() 
   }
;

    
for each ( Animal ^in animals)
    
{
        a
->Speak();
    }

    Console::WriteLine();

    
for each ( Animal ^in animals)
    
{
        a
->Eat();
    }


 Tiger
^ dd = gcnew Tiger;
 dd
->Speak();

 Console::ReadLine();
}


最后的结果
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的覆盖。是不是对基类的覆盖优先呢。暂时可以这么理解吧。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值