静态成员函数可以通过基类或者派生类的作用域来访问。

📅 2026/7/2 1:59:30
静态成员函数可以通过基类或者派生类的作用域来访问。
class Base {public:static int s_count;static void printCount() {std::cout Count: s_count std::endl;}};int Base::s_count 0; // 静态成员初始化class Derived : public Base {// ...};int main() {Base b;Derived d;b.s_count 10;d.s_count 20; // 修改的是同一个 s_countBase::printCount(); // 输出 Count: 20Derived::printCount(); // 输出 Count: 20return 0;}2.3.7 多继承和菱形继承问题多继承会引入复杂性最主要的问题是命名冲突。如果多个基类中有同名的成员那么在派生类中访问时必须使用作用域解析符来明确指出要访问哪个基类的成员。class A {public:void foo() { std::cout A::foo() std::endl; }};class B {public:void foo() { std::cout B::foo() std::endl; }};class C : public A, public B {// ...};int main() {C c;// c.foo(); // 错误对 foo 的访问不明确c.A::foo(); // 正确调用A的fooc.B::foo(); // 正确调用B的fooreturn 0;}菱形继承当一个派生类通过多个路径继承同一个基类时就会形成菱形结构。/******************************************************************************************************Person/ \Teacher Student\ /TeachingAssistantPerson 类Teacher 类继承 PersonStudent 类继承 Person******************************************************************************************************/class Person {public:int m_age;};class Teacher : public Person {};class Student : public Person {};class TeachingAssistant : public Teacher, public Student {};int main() {TeachingAssistant ta;// ta.m_age 25; // 错误对 m_age 的访问不明确ta.Teacher::m_age 25; // 修改Teacher路径上的m_ageta.Student::m_age 26; // 修改Student路径上的m_age// 现在ta对象中有两个不同的m_age值数据不一致了return 0;}菱形继承会导致内存浪费数据不一致访问二义性。虚继承为解决菱形继承的问题引入的虚继承。作用虚继承确保在继承体系中无论被继承多少次共享的基类如 Person只会有一个实例。语法在继承路径的“腰部”使用 virtual 关键字。即在直接继承共同基类的派生类Teacher 和 Student的继承声明中使用 virtual。class Person {public:int m_age;};// 使用虚继承class Teacher : virtual public Person {};class Student : virtual public Person {};class TeachingAssistant : public Teacher, public Student {};int main() {TeachingAssistant ta;ta.m_age 25; // 正确不再有二义性因为只有一个m_agestd::cout ta.m_age std::endl; // 输出 25std::cout ta.Teacher::m_age std::endl; // 输出 25 (同一个)std::cout ta.Student::m_age std::endl; // 输出 25 (同一个)return 0;}虚继承的原理简述虚继承的实现通常通过虚基类指针和虚基类表。每个继承了虚基类的类如 Teacher, Student的对象中会多一个虚基类指针。这个指针指向一个虚基类表表中记录了从当前对象位置到共享的虚基类Person子对象的偏移量。这样无论通过 Teacher 还是 Student 的路径都能通过查表找到同一个 Person 子对象。2.3.8 同名成员分为同名成员变量的处理和同名成员函数的处理。只要派生类中存在与基类同名的函数那基类中所有的重载函数都会被隐藏必须使用作用域的方式调用。核心思想是派生类的同名成员会“隐藏”基类的同名成员使得通过派生类对象直接访问时只能访问到派生类自己的版本。#include iostream#include stringclass Base {public:int m_value; // 基类的成员变量Base() : m_value(100) {std::cout Base constructor, m_value m_value std::endl;}};class Derived : public Base {public:int m_value; // 派生类的同名成员变量Derived() : m_value(200) {std::cout Derived constructor, m_value m_value std::endl;}void printValues() {std::cout --- Inside Derived::printValues --- std::endl;// 直接访问 m_value访问的是派生类自己的 m_valuestd::cout Deriveds m_value m_value std::endl;// 使用作用域解析运算符 :: 来访问被隐藏的基类成员std::cout Bases m_value Base::m_value std::endl;std::cout ---------------------------------- std::endl;}};int main() {Derived d;d.printValues();// 通过对象直接访问std::cout --- Accessing via object --- std::endl;std::cout d.m_value d.m_value std::endl; // 访问的是 Derived::m_value// 如何通过对象访问基类的 m_value// 必须使用作用域解析运算符std::cout d.Base::m_value d.Base::m_value std::endl; // 访问的是 Base::m_valuereturn 0;}