如何深入探讨虚函数的运用技巧?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1632个文字,预计阅读时间需要7分钟。
目录
一、虚函数
二、虚函数与纯虚函数的区别
三、动态多态
四、虚函数作用和原理、纯虚函数与虚函数的区别
一、虚函数
首先来看下面这段代码,创建两个类,Dog和Cat,并定义一个函数用于展示它们的叫声:cppclass Animal {public: virtual void makeSound()=0; // 纯虚函数};
class Dog : public Animal {public: void makeSound() override { std::cout << Woof! < class Cat : public Animal {public: void makeSound() override { std::cout << Meow! < int main() { Animal *animal1=new Dog(); Animal *animal2=new Cat(); animal1->makeSound(); // 输出:Woof! animal2->makeSound(); // 输出:Meow! delete animal1; delete animal2; return 0;} 在上面的代码中,`Animal` 类定义了一个纯虚函数 `makeSound()`,这意味着任何继承自 `Animal` 的类都必须实现这个函数。`Dog` 和 `Cat` 类继承自 `Animal` 并分别实现了 `makeSound()` 函数。 二、虚函数与纯虚函数的区别虚函数允许在运行时根据对象的实际类型来调用相应的函数,而纯虚函数是一个没有具体实现的虚函数,它要求任何继承自该类的子类都必须提供自己的实现。 三、动态多态在上面的代码中,`makeSound()` 函数的调用是根据对象的实际类型来决定的,这称为动态多态。动态多态允许通过基类指针或引用调用派生类中的函数。 四、虚函数作用和原理、纯虚函数与虚函数的区别虚函数的主要作用是实现动态多态,允许根据对象的实际类型调用相应的函数。虚函数的原理是通过虚函数表(vtable)来实现的,每个类都有一个虚函数表,表中包含了该类所有虚函数的地址。 纯虚函数与虚函数的主要区别在于,纯虚函数没有具体的实现,而虚函数有具体的实现。纯虚函数用于定义一个抽象基类,而虚函数用于实现动态多态。 阐述虚函数作用和原理、纯虚函数和虚函数的区别。 首先来看下面这一段代码,首先创建两个类,一个是Dog,另一个是Cat,他们有一个共同的属性:Run。在定义中每个动物都需要创建一个类,比较繁琐,所以在下面的例子中,我们可以把他们简化。 #include <iostream>
using namespace std;
class Dog{
public:
void Run(){
cout<<"Dog->Run"<<endl;
}
};
class Cat{
public:
void Run(){
cout<<"Cat->Run"<<endl;
}
};
int main()
{
Dog d;
d.Run();
Cat c;
c.Run();
return 0;
}
这里使用多态和虚函数,而Animal提供统一的接口,供子类使用,虽然代码繁琐,但提高了整个工程的可扩展性和灵活性。 在普通函数前加上关键字 virtual 构成虚函数,子类需要重写父类的虚函数,这样在调用的时候,会覆盖掉父类的虚函数 Run,去执行子类的Run。 #include <iostream>
using namespace std;
class Animal{
public:
virtual void Run(){
cout<<"Animal->Run"<<endl;
}
};
class Dog :public Animal{
public:
void Run(){
cout<<"Dog->Run"<<endl;
}
};
class Cat:public Animal{
public:
void Run(){
cout<<"Cat->Run"<<endl;
}
};
int main()
{
Animal *ani;
ani = new Dog;
ani->Run();
delete ani;
ani = new Cat;
ani->Run();
delete ani;
return 0;
}
结果如下: 所以在这里只需要修改ani的指向就可以实现不同方法。如果不存在虚函数,把Animal类的关键词virtual去掉会怎么样呢,显然,他们会默认实现父类Run的方法。 class Animal{
public:
void Run(){
cout<<"Animal->Run"<<endl;
}
};
所以引入虚函数是为了实现动态多态,指向不同的子类来实现不同的方法。 因为父类的函数可以不做任何操作,所以这里可以直接等于0;实现纯虚函数。 //虚函数
class Animal{
public:
virtual void Run(){
cout<<"Animal->Run"<<endl;
}
};
//纯虚函数
class Animal{
public:
virtual void Run()=0;
};
虚函数与纯虚函数的区别: 纯虚函数只是一个接口,只能供子类去重写实现方法。而虚函数在里面也可以去实现父类的功能。只需要指向父类的方法即可。 总结:虚函数在子类里面也可以不进行重写,但纯虚函数必须在子类去实现,如果把子类中的Run方法去掉,只留下父类中的纯虚函数,那么编译器会报错,这里大家可以试试。 Animal内部的结构是什么样呢?这里有一个虚函数指针(vfptr)和虚函数表(vftable)。 指针(vfptr)指向虚函数表,在虚函数表(vftable)内记录着虚函数的地址,即Run函数的地址。 当子类的Dog去继承父类后,父类的虚函数表相应的也继承下来,子类也会保存一份和父类相同的。 注意!这时候如果发生重写,即子类重写了父类的虚函数,则子类的虚函数表会覆盖父类继承下来的虚函数表。但父类的虚函数表不会发生改变。 当父类的指针或者引用指向子类的对象时,就发生了多态。 下面的代码中是指向了Dog,所以会去Dog的虚函数表中找到相应的函数,在运行阶段发生了动态多态。 Animal *ani;
ani = new Dog;
ani->Run();
到此这篇关于C++浅析虚函数使用方法的文章就介绍到这了,更多相关C++虚函数内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!目录
一、虚函数
二、虚函数与纯虚函数的区别
三、动态多态
本文共计1632个文字,预计阅读时间需要7分钟。
目录
一、虚函数
二、虚函数与纯虚函数的区别
三、动态多态
四、虚函数作用和原理、纯虚函数与虚函数的区别
一、虚函数
首先来看下面这段代码,创建两个类,Dog和Cat,并定义一个函数用于展示它们的叫声:cppclass Animal {public: virtual void makeSound()=0; // 纯虚函数};
class Dog : public Animal {public: void makeSound() override { std::cout << Woof! < class Cat : public Animal {public: void makeSound() override { std::cout << Meow! < int main() { Animal *animal1=new Dog(); Animal *animal2=new Cat(); animal1->makeSound(); // 输出:Woof! animal2->makeSound(); // 输出:Meow! delete animal1; delete animal2; return 0;} 在上面的代码中,`Animal` 类定义了一个纯虚函数 `makeSound()`,这意味着任何继承自 `Animal` 的类都必须实现这个函数。`Dog` 和 `Cat` 类继承自 `Animal` 并分别实现了 `makeSound()` 函数。 二、虚函数与纯虚函数的区别虚函数允许在运行时根据对象的实际类型来调用相应的函数,而纯虚函数是一个没有具体实现的虚函数,它要求任何继承自该类的子类都必须提供自己的实现。 三、动态多态在上面的代码中,`makeSound()` 函数的调用是根据对象的实际类型来决定的,这称为动态多态。动态多态允许通过基类指针或引用调用派生类中的函数。 四、虚函数作用和原理、纯虚函数与虚函数的区别虚函数的主要作用是实现动态多态,允许根据对象的实际类型调用相应的函数。虚函数的原理是通过虚函数表(vtable)来实现的,每个类都有一个虚函数表,表中包含了该类所有虚函数的地址。 纯虚函数与虚函数的主要区别在于,纯虚函数没有具体的实现,而虚函数有具体的实现。纯虚函数用于定义一个抽象基类,而虚函数用于实现动态多态。 阐述虚函数作用和原理、纯虚函数和虚函数的区别。 首先来看下面这一段代码,首先创建两个类,一个是Dog,另一个是Cat,他们有一个共同的属性:Run。在定义中每个动物都需要创建一个类,比较繁琐,所以在下面的例子中,我们可以把他们简化。 #include <iostream>
using namespace std;
class Dog{
public:
void Run(){
cout<<"Dog->Run"<<endl;
}
};
class Cat{
public:
void Run(){
cout<<"Cat->Run"<<endl;
}
};
int main()
{
Dog d;
d.Run();
Cat c;
c.Run();
return 0;
}
这里使用多态和虚函数,而Animal提供统一的接口,供子类使用,虽然代码繁琐,但提高了整个工程的可扩展性和灵活性。 在普通函数前加上关键字 virtual 构成虚函数,子类需要重写父类的虚函数,这样在调用的时候,会覆盖掉父类的虚函数 Run,去执行子类的Run。 #include <iostream>
using namespace std;
class Animal{
public:
virtual void Run(){
cout<<"Animal->Run"<<endl;
}
};
class Dog :public Animal{
public:
void Run(){
cout<<"Dog->Run"<<endl;
}
};
class Cat:public Animal{
public:
void Run(){
cout<<"Cat->Run"<<endl;
}
};
int main()
{
Animal *ani;
ani = new Dog;
ani->Run();
delete ani;
ani = new Cat;
ani->Run();
delete ani;
return 0;
}
结果如下: 所以在这里只需要修改ani的指向就可以实现不同方法。如果不存在虚函数,把Animal类的关键词virtual去掉会怎么样呢,显然,他们会默认实现父类Run的方法。 class Animal{
public:
void Run(){
cout<<"Animal->Run"<<endl;
}
};
所以引入虚函数是为了实现动态多态,指向不同的子类来实现不同的方法。 因为父类的函数可以不做任何操作,所以这里可以直接等于0;实现纯虚函数。 //虚函数
class Animal{
public:
virtual void Run(){
cout<<"Animal->Run"<<endl;
}
};
//纯虚函数
class Animal{
public:
virtual void Run()=0;
};
虚函数与纯虚函数的区别: 纯虚函数只是一个接口,只能供子类去重写实现方法。而虚函数在里面也可以去实现父类的功能。只需要指向父类的方法即可。 总结:虚函数在子类里面也可以不进行重写,但纯虚函数必须在子类去实现,如果把子类中的Run方法去掉,只留下父类中的纯虚函数,那么编译器会报错,这里大家可以试试。 Animal内部的结构是什么样呢?这里有一个虚函数指针(vfptr)和虚函数表(vftable)。 指针(vfptr)指向虚函数表,在虚函数表(vftable)内记录着虚函数的地址,即Run函数的地址。 当子类的Dog去继承父类后,父类的虚函数表相应的也继承下来,子类也会保存一份和父类相同的。 注意!这时候如果发生重写,即子类重写了父类的虚函数,则子类的虚函数表会覆盖父类继承下来的虚函数表。但父类的虚函数表不会发生改变。 当父类的指针或者引用指向子类的对象时,就发生了多态。 下面的代码中是指向了Dog,所以会去Dog的虚函数表中找到相应的函数,在运行阶段发生了动态多态。 Animal *ani;
ani = new Dog;
ani->Run();
到此这篇关于C++浅析虚函数使用方法的文章就介绍到这了,更多相关C++虚函数内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!目录
一、虚函数
二、虚函数与纯虚函数的区别
三、动态多态

