C/C++|每日一练(2)
- 游戏开发
- 2025-09-04 22:42:02

💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥
文章目录 C/C++ | 每日一练 (2)题目参考答案封装继承多态虚函数底层实现单继承多继承 注意事项 C/C++ | 每日一练 (2) 题目简述 c++ 面向对象的三大特性。
参考答案面向对象三大特性:封装、继承、多态。
封装封装指的是将对象的行为和属性结合成为一个类,并隐藏对象的内部实现细节,仅通过对象的接口(即公开的方法)与外界交互。
隐藏内部实现细节:保护对象的内部状态,防止外部直接访问或修改对象的私有成员。提供统一的接口:通过公开的方法(如构造函数、成员函数等)对外提供服务,使对象的使用更加安全和方便。例如:
#include <iostream> class Person { private: // 私有成员,外部无法直接访问 std::string name; int age; public: // 提供接口访问私有成员 void setName(const std::string &newName) { name = newName; } void setAge(int newAge) { age = newAge; } void display() const { std::cout << name << " is " << age << " years old." << std::endl; } }; 继承继承是指一个类(派生类或子类)可以继承另一个类(基类或父类)的属性和方法。子类可以扩展或修改父类的功能,而无需重新编写相同的代码,支持代码重用和扩展。继承可以是单继承或多继承(在 c++ 中支持)
继承的主要作用是:
代码复用:减少重复代码,提高开发效率。拓展功能:派生类可以在继承基类的基础上,添加新的功能或修改现有功能。 #include <iostream> class Animal { public: void eat() { std::cout << "animal eat" << std::endl; } }; class Dog : public Animal { public: void bark() { std::cout << "dog eat" << std::endl; } }; 多态多态是指相同的接口在不同的类实例上具有不同的表现形式。多态分为:
编译时多态(函数重载和运算符重载)
运行时多态(通过虚函数实现)。
运行时多态是面向对象编程中最重要的多态形式,它通过虚函数和继承实现。
例如:
#include <iostream> class Shape { public: // 定义为虚函数 virtual void draw() const { std::cout << "drawing a shape" << std::endl; } }; class Circle : public Shape { public: // 重写基类的虚函数 void draw() const override { std::cout << "drawing a circle" << std::endl; } }; class Square : public Shape { public: // 重写基类的虚函数 void draw() const override { std::cout << "drawing a square" << std::endl; } }; int main() { Shape *s1 = new Circle(); Shape *s2 = new Square(); s1->draw(); // drawing a circle s2->draw(); // drawing a square delete s1; delete s2; } 虚函数在 c++ 中,虚函数是实现运行时多态的关键机制。它允许派生类重写继承自基类的成员函数,从而在运行时根据对象的实际类型调用相应的函数实现。
虚函数是在基类中通过关键字 virtual 声明的成员函数。它的作用是让派生类可以覆盖该函数,从而实现多态行为。
#include <iostream> class Base { public: virtual void display() { std::cout << "Base::display()" << std::endl; } }虚函数的主要作用是实现 动态绑定或运行时多态。具体来说:
当通过基类指针或引用调用虚函数时,程序会根据对象的实际类型(派生类类型)来调用对应的函数实现。如果没有虚函数,调用的将是基类的成员函数,而不是派生类的实现,这种行为称为静态绑定。 #include <iostream> class Base { public: virtual void display() { std::cout << "Base::display()" << std::endl; } }; class Derived : public Base { public: // 重写基类的虚函数 void display() override { std::cout << "Derived::display()" << std::endl; } }; int main() { Base* ptr = new Derived(); delete ptr; return 0; }在上述代码中,ptr 是基类指针指向子类对象,由于 display() 是虚函数,程序会调用派生类的 display() 的实现。
底层实现虚函数的实现依赖于虚表(简称 vtable)和虚表指针(vptr):
每个包含虚函数的类都有一个虚表(vtable),虚表中存储了该类中所有虚函数的地址。每个对象在对象头中会隐式地包含一个虚表指针(vptr),指向其所属类的虚表。当通过基类指针或引用调用虚函数时,程序会通过 vptr 查找虚表,然后在虚表中根据函数索引找到正确的函数地址。执行函数调用。 单继承单继承的动态多态结构图如下所示:
多继承多继承是 c++ 中的一种继承方式,它允许一个子类从多个基类继承属性和行为。这种继承方式可以提供更大的灵活性,使得派生类能够组合多个基类的特性。但是,多继承也引入了复杂性,尤其是在内存布局、虚函数表、构造和析构顺序等方面。多继承的动态多态结构图如下所示:
#include <iostream> class Base1 { public: virtual void display() { std::cout << "Base1::display()" << std::endl; } virtual void show() { std::cout << "Base1::show()" << std::endl; } virtual ~Base1() { std::cout << "Base1::~Base1()" << std::endl; } private: int a; int b; }; class Base2 { public: virtual void cat() { std::cout << "Base2::cat()" << std::endl; } virtual ~Base2() { std::cout << "Base2::~Base2()" << std::endl; } private: int c; }; class Derived : public Base1, public Base2 { public: // 重写基类的虚函数 void display() override { std::cout << "Derived::display()" << std::endl; } void cat() override { std::cout << "Derived::cat()" << std::endl; } ~Derived() override { std::cout << "Derived::~Derived" << std::endl; } private: int d; }; int main() { Base1* ptr1 = new Derived(); Base2* ptr2 = new Derived(); delete ptr1; delete ptr2; return 0; } 注意事项 虚函数必须是成员函数:全局函数或静态成员函数不能声明为虚函数。派生类的覆盖函数必须与基类的虚函数具有相同的签名(函数名、参数类型和数量)。如果派生类的函数与基类虚函数签名不一致(函数名相同,参数类型和数量不相同),则不会覆盖而是隐藏。纯虚函数:在基类中,可以将虚函数声明为纯虚函数,即在声明时赋值为 = 0。包含纯虚函数的类称为抽象类,不能实例化对象。 class AbstractClass { public: virtual void func() = 0; // 纯虚函数 }; 析构函数的虚化:如果基类有虚函数,通常需要将析构函数声明为虚函数,以确保通过基类指针删除派生类对象时,能够正确调用派生类的析构函数。 class Base { public: virtual ~Base() { cout << "Base destructor" << endl; } }; class Derived : public Base { public: ~Derived() { cout << "Derived destructor" << endl; } }; 虚函数的实现依赖于虚表和虚表指针,因此会带来一定的性能开销;每个对象需要存储一个虚表指针(通常为 4 字节或 8 字节)。动态多态在调用虚函数时需要通过虚表查找函数地址,这比直接调用非虚函数稍慢。但是这种开销通常是可以接受的,特别是在需要多态的场景中。🌺🌺🌺撒花!
如果本文对你有帮助,就点关注或者留个👍 如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。
C/C++|每日一练(2)由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C/C++|每日一练(2)”
上一篇
git在工作流程中的使用
下一篇
go设置镜像代理