虚 函数
目的
编辑
- 调用
到 基 类的方法 :编译器 根 据 指 针或引用 的 类型决定,称 作 「早 绑定」; - 调用
到 派生 类的方法 :语言的 运行时系统根据 对象的 实际类型决定,称 作 「迟绑定 」。
virtual
程 式 範 例
编辑
Animal
eat
。Fish
eat()
,這個Fish
Wolf
eat()
Fish
eat()
C++
编辑# include <iostream>
# include <vector>
using namespace std;
class Animal
{
public:
virtual void eat() const { cout << "I eat like a generic Animal." << endl; }
virtual ~Animal() {}
};
class Wolf : public Animal
{
public:
void eat() const { cout << "I eat like a wolf!" << endl; }
};
class Fish : public Animal
{
public:
void eat() const { cout << "I eat like a fish!" << endl; }
};
class GoldFish : public Fish
{
public:
void eat() const { cout << "I eat like a goldfish!" << endl; }
};
class OtherAnimal : public Animal
{
};
int main()
{
std::vector<Animal*> animals;
animals.push_back( new Animal() );
animals.push_back( new Wolf() );
animals.push_back( new Fish() );
animals.push_back( new GoldFish() );
animals.push_back( new OtherAnimal() );
for( std::vector<Animal*>::const_iterator it = animals.begin();
it != animals.end(); ++it)
{
(*it)->eat();
delete *it;
}
return 0;
}
Animal::eat()
I eat like a generic Animal. I eat like a wolf! I eat like a fish! I eat like a goldfish! I eat like a generic Animal.
Animal::eat()
I eat like a generic Animal. I eat like a generic Animal. I eat like a generic Animal. I eat like a generic Animal. I eat like a generic Animal.
Java
编辑import java.util.*;
public class Animal {
public void eat() { System.out.println("I eat like a generic Animal."); }
public static void main(String[] args) {
List<Animal> animals = new LinkedList<Animal>();
animals.add(new Animal());
animals.add(new Wolf());
animals.add(new Fish());
animals.add(new OtherAnimal());
for (Animal currentAnimal : animals) {
currentAnimal.eat();
}
}
}
public class Wolf extends Animal {
public void eat() { System.out.println("I eat like a wolf!"); }
}
public class Fish extends Animal {
public void eat() { System.out.println("I eat like a fish!"); }
}
public class OtherAnimal extends Animal {}
输出:
I eat like a generic Animal. I eat like a wolf! I eat like a fish! I eat like a generic Animal.
C#
编辑virtual
override
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
public class Animal
{
public virtual void Eat()
{
Console.WriteLine("I eat like a generic Animal.");
}
}
public class Wolf : Animal
{
public override void Eat()
{
Console.WriteLine("I eat like a wolf!");
}
}
public class Fish : Animal
{
public override void Eat()
{
Console.WriteLine("I eat like a fish!");
}
}
public class GoldFish : Fish
{
public override void Eat()
{
Console.WriteLine("I eat like a goldfish!");
}
}
public class OtherAnimal : Animal
{
// Eat() method is not overridden, so the base class method will be used.
}
public class Program
{
public static void Main(string[] args)
{
IList<Animal> animals = new List<Animal>();
animals.Add(new Animal());
animals.Add(new Wolf());
animals.Add(new Fish());
animals.Add(new GoldFish());
animals.Add(new OtherAnimal());
foreach (Animal currentAnimal in animals)
{
currentAnimal.Eat();
}
}
}
}
输出:
I eat like a generic Animal. I eat like a wolf! I eat like a fish! I eat like a goldfish! I eat like a generic Animal.
抽象 类和纯虚函数
编辑
纯虚
doOperation()
, doOperation()
doOperation()
doOperation()
虽然纯虚
C++
编辑class Abstract {
public:
virtual void pure_virtual() = 0;
};
纯虚
void Abstract::pure_virtual() {
// do something
}
class Child : public Abstract {
virtual void pure_virtual(); // no longer abstract, this class may be
// instantiated.
};
void Child::pure_virtual() {
Abstract::pure_virtual(); // the implementation in the abstract class
// is executed
}
构造与 析构时的行 为
编辑
参考 文献
编辑
- ^ MSDN "Using dllimport and dllexport in C++ Classes" (页面
存 档备份,存 于互联网档案 馆): However, because a destructor for an abstract class is always called by the destructor for the base class, pure virtual destructors must always provide a definition. Note that these rules are the same for nonexportable classes. - ^ Standard C++ 98 - 10.4/2
- ^ Meyers, Scott. Never Call Virtual Functions during Construction or Destruction. June 6, 2005 [2018-06-22]. (
原始 内容 存 档于2021-01-26).
- C++ FAQ Lite Copyright © 1991-2006, Marshall Cline.