c++中如何实现继承_c++子类继承父类的基本语法【详解】

子类声明必须显式指定public、protected或private继承方式,决定父类成员访问权限;构造函数不继承,需在初始化列表中显式调用父类构造函数;同名函数会隐藏而非覆盖父类版本,须用Base::func()访问。

c++中如何实现继承_c++子类继承父类的基本语法【详解】

子类声明时如何指定继承方式

继承方式决定父类成员在子类中的访问权限,必须显式写出,不能省略。C++ 支持三种:publicprotectedprivate,最常用的是 public 继承。

  • public 继承:父类的 public 成员在子类中仍为 publicprotected 保持 protectedprivate 不可访问
  • protected 继承:父类所有非 private 成员在子类中变为 protected
  • private 继承(极少用):父类所有非 private 成员在子类中变为 private

错误写法:class Derived : Base —— 缺少冒号和继承关键字,编译报错:expected ‘:’ before ‘{’ token

构造函数不能被继承,但必须显式调用父类构造函数

C++11 起支持使用 using 声明继承部分构造函数(仅限无默认参数、无重载冲突的情况),但绝大多数场景下,子类需自己定义构造函数,并在初始化列表中调用父类构造函数。

  • 父类没有默认构造函数时,子类构造函数**必须**在初始化列表中显式调用父类带参构造函数
  • 遗漏调用会导致编译错误no matching function for call to ‘Base::Base()’
  • 若父类有默认构造函数,不显式调用也不会报错,但逻辑可能不符合预期(比如父类成员未按需初始化)
class Base {
public:
    Base(int x) : val(x) {}
private:
    int val;
};

class Derived : public Base {
public:
    Derived(int x, int y) : Base(x), data(y) {} // ✅ 正确:显式调用 Base(int)
private:
    int data;
};

子类中访问父类同名成员需注意作用域与隐藏规则

子类定义了与父类同名的函数(无论参数是否相同),父类该名字的所有重载版本都会被**隐藏**,而非重载或覆盖。这是初学者最常踩的坑。

Axiom

Axiom

Axiom是一个浏览器扩展,用于自动化重复任务和web抓取。

下载

立即学习C++免费学习笔记(深入)”;

  • 想调用被隐藏的父类函数,必须用作用域解析符:Base::func()
  • 仅当子类函数签名与父类虚函数完全一致且加了 override,才是覆盖(override);否则是隐藏(hiding)
  • 数据成员同名也会隐藏,但通常应避免——编译器不会报错,但语义混乱
class Base {
public:
    void print() { std::cout << "Base/n"; }
    void print(int x) { std::cout << "Base " << x << "/n"; }
};

class Derived : public Base {
public:
    void print() override { std::cout << "Derived/n"; } // 隐藏了 Base::print() 和 Base::print(int)
    // 下面这行会编译失败,除非显式写 Base::print(42)
    // void foo() { print(42); }
    void foo() { Base::print(42); } // ✅ 显式调用
};

多重继承时要注意菱形继承与虚基类

当两个父类都继承自同一个祖父类,而子类又同时继承这两个父类时,若不使用 virtual,子类会包含两份祖父类子对象,引发二义性和内存冗余。

  • 解决方法:在中间继承路径上使用 virtual public Base
  • 虚基类的构造函数由**最派生类**直接调用,中间类的初始化列表中对虚基类构造函数的调用会被忽略
  • 虚继承带来轻微性能开销(额外指针、间接寻址),仅在必要时使用

典型错误现象:error: ‘Base’ is an ambiguous base of ‘Derived’,或访问 Base 成员时报二义性。

继承本身不难写,难的是理解“什么被继承”“什么没被继承”“谁负责初始化”以及“名字查找怎么走”。尤其在涉及多态、模板和虚继承时,编译器的行为往往反直觉。写完继承结构后,建议用 sizeof 检查布局,用 gdbclang -cc1 -ast-dump 看实际符号解析路径。

https://www.php.cn/faq/2022668.html

发表回复

Your email address will not be published. Required fields are marked *