欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 「C/C++」C++ 三大特性 之 继承

「C/C++」C++ 三大特性 之 继承

2025/2/23 22:47:41 来源:https://blog.csdn.net/qq_49443542/article/details/143357286  浏览:    关键词:「C/C++」C++ 三大特性 之 继承

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

目录

    • C++ 继承中的函数详解
      • 1. 函数的继承
      • 2. 函数的重写(覆盖)
      • 3. 函数的隐藏
      • 4. 多态性
      • 5. 函数访问权限的变化
      • 6. 详细示例
      • 总结

C++ 继承中的函数详解

在C++面向对象编程中,继承是一种强大的机制,它允许我们创建一个新的类(派生类)来继承另一个类(基类)的属性和方法。这种机制促进了代码的重用和扩展性。在继承关系中,基类的成员函数在派生类中仍然有效,并且可以根据需要进行重写或扩展。本文将详细探讨C++继承中的函数,包括函数的继承、重写(覆盖)、隐藏、多态性以及函数访问权限的变化。

1. 函数的继承

当派生类从基类继承时,基类的公有成员函数和保护成员函数会自动成为派生类的成员。这些成员在派生类中具有与在基类中相同的访问权限(除非在派生类中被进一步限制)。

class Base {
public:void publicFunc() { /* ... */ }
protected:void protectedFunc() { /* ... */ }
};class Derived : public Base {// Base::publicFunc() 和 Base::protectedFunc() 都是 Derived 的成员
};

在上面的例子中,Derived 类继承了 Base 类的 publicFunc()protectedFunc() 成员函数。publicFunc()Derived 类中仍然是公有的,而 protectedFunc()Derived 类中保持保护状态。

2. 函数的重写(覆盖)

重写(也称为覆盖)是指在派生类中重新定义基类中已经存在的虚函数。要重写一个函数,派生类中的函数必须具有与基类中的虚函数相同的名称、返回类型和参数列表。

class Base {
public:virtual void virtualFunc() { /* 基类实现 */ }
};class Derived : public Base {
public:// 重写基类的虚函数void virtualFunc() override { /* 派生类实现 */ }
};

在上面的例子中,Derived 类重写了 Base 类的 virtualFunc() 成员函数。override 关键字是C++11引入的,它用于明确指出一个函数是重写基类中的虚函数,如果重写不正确,编译器会报错。

3. 函数的隐藏

与重写不同,如果派生类定义了一个与基类中的非虚函数同名的函数(即使参数列表不同),那么基类的该函数在派生类作用域内将被隐藏。这意味着通过派生类对象或指针无法访问基类的同名函数。

class Base {
public:void func() { /* 基类实现 */ }
};class Derived : public Base {
public:// 隐藏基类的 func() 函数void func(int) { /* 派生类实现 */ }
};int main() {Derived d;d.func(1); // 调用 Derived::func(int)// d.func(); // 错误:无法访问隐藏的 Base::func()Base* b = &d;b->func(); // 调用 Base::func(),因为 b 是基类指针return 0;
}

在上面的例子中,Derived 类定义了一个与 Base 类中的 func() 同名的函数,但参数列表不同。这导致 Base 类的 func() 函数在 Derived 类作用域内被隐藏。

4. 多态性

多态性是面向对象编程的一个重要特性,它允许我们通过基类指针或引用来调用派生类中的重写函数。要实现多态性,基类中的函数必须是虚函数。

class Base {
public:virtual void show() { std::cout << "Base show" << std::endl; }virtual ~Base() = default; // 虚析构函数,确保正确调用派生类的析构函数
};class Derived : public Base {
public:void show() override { std::cout << "Derived show" << std::endl; }
};int main() {Base* b1 = new Base();Base* b2 = new Derived(); // 基类指针指向派生类对象b1->show(); // 调用 Base::show()b2->show(); // 调用 Derived::show(),体现多态性delete b1;delete b2;return 0;
}

在上面的例子中,b2 是一个基类指针,但它指向一个 Derived 对象。当我们调用 b2->show() 时,实际上调用的是 Derived 类中的 show() 函数,这就是多态性的体现。

5. 函数访问权限的变化

在继承中,基类的成员函数在派生类中的访问权限可能会发生变化。如果基类中的函数是公有的,那么在派生类中它仍然是公有的(除非在派生类中被进一步限制)。如果基类中的函数是保护的或私有的,那么在派生类中它仍然保持相应的访问权限。

然而,需要注意的是,即使基类中的函数是保护的或私有的,派生类仍然可以通过基类指针或引用来调用这些函数(如果它们是虚函数并被重写)。这是因为虚函数调用是在运行时解析的,而不是在编译时。

class Base {
protected:void protectedFunc() { /* ... */ }
private:void privateFunc() { /* ... */ }
public:virtual void virtualFunc() { /* 基类实现 */ }
};class Derived : public Base {
public:// 无法直接访问 Base::privateFunc(),因为它在基类中是私有的// 但可以重写 Base::virtualFunc()void virtualFunc() override { /* 派生类实现 */ }// 可以访问 Base::protectedFunc(),因为它在基类中是保护的void callProtectedFunc() {protectedFunc(); // 合法// privateFunc(); // 错误:无法访问基类的私有成员函数}
};

6. 详细示例

#include <iostream>  
#include <cstring>  // 基类  
class Base {  
private:  char* data;  public:  // 基类的构造函数,用于分配内存  Base(const char* str = "") {  data = new char[strlen(str) + 1];  strcpy(data, str);  std::cout << "Base constructor called, data: " << data << std::endl;  }  // 基类的虚析构函数,确保正确调用派生类的析构函数  virtual ~Base() {  std::cout << "Base destructor called, deleting data: " << data << std::endl;  delete[] data;  }  // 基类的虚函数,用于演示多态性  virtual void show() {  std::cout << "Base show, data: " << data << std::endl;  }  
};  // 派生类  
class Derived : public Base {  
private:  int value;  public:  // 派生类的构造函数,调用基类的构造函数并初始化自己的成员  Derived(int val, const char* str = "") : Base(str), value(val) {  std::cout << "Derived constructor called, value: " << value << std::endl;  }  // 派生类的析构函数,确保在基类析构函数之后调用  ~Derived() {  std::cout << "Derived destructor called, value: " << value << std::endl;  }  // 重写基类的虚函数  void show() override {  std::cout << "Derived show, value: " << value << ", data: " << Base::data << std::endl;  }  
};  int main() {  // 创建派生类对象,并调用构造函数和析构函数  Derived d(42, "Hello from Derived");  d.show(); // 调用派生类的 show() 函数  // 通过基类指针创建派生类对象,并调用构造函数和析构函数  Base* b = new Derived(100, "Hello from Base pointer to Derived");  b->show(); // 调用派生类的 show() 函数,体现多态性  // 释放内存  delete b; // 先调用派生类的析构函数,然后调用基类的析构函数  // 注意:main 函数结束时,d 对象会自动调用其析构函数  return 0;  
}

总结

C++ 继承中的函数涉及多个方面,包括函数的继承、重写(覆盖)、隐藏、多态性以及函数访问权限的变化。理解这些概念对于深入掌握C++的面向对象编程至关重要。通过合理地使用继承机制,我们可以创建更加灵活和可扩展的代码结构。


在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词