基本概念

C++类的继承有共有继承,保护继承和私有继承

以下是每种继承方式,以及对应的权限的变更

  1. // C++ Implementation to show that a derived class
  2. // doesn’t inherit access to private data members.
  3. // However, it does inherit a full parent object
  4. class A
  5. {
  6. public:
  7. int x;
  8. protected:
  9. int y;
  10. private:
  11. int z;
  12. };
  13. class B : public A
  14. {
  15. // x is public
  16. // y is protected
  17. // z is not accessible from B
  18. };
  19. class C : protected A
  20. {
  21. // x is protected
  22. // y is protected
  23. // z is not accessible from C
  24. };
  25. class D : private A // 'private' is default for classes
  26. {
  27. // x is private
  28. // y is private
  29. // z is not accessible from D
  30. };

public

// C++ program to demonstrate public
// access modifier

#include<iostream>
using namespace std;

// class definition
class Circle
{
    public: 
        double radius;

        double  compute_area()
        {
            return 3.14*radius*radius;
        }

};

// main function
int main()
{
    Circle obj;

    // accessing public datamember outside class
    obj.radius = 5.5;

    cout << "Radius is: " << obj.radius << "\n";
    cout << "Area is: " << obj.compute_area();
    return 0;
}

//Output
Radius is: 5.5
Area is: 94.985

private

// C++ program to demonstrate private
// access modifier

#include<iostream>
using namespace std;

class Circle
{   
    // private data member
    private: 
        double radius;

    // public member function    
    public:    
        double  compute_area()
        {   // member function can access private 
            // data member radius
            return 3.14*radius*radius;
        }

};

// main function
int main()
{   
    // creating object of the class
    Circle obj;

    // trying to access private data member
    // directly outside the class
    obj.radius = 1.5;

    cout << "Area is:" << obj.compute_area();
    return 0;
}

//Output
In function 'int main()':
11:16: error: 'double Circle::radius' is private
         double radius;
                ^
31:9: error: within this context
     obj.radius = 1.5;

protected

protected 和private的唯一区别在于,允许子类访问父类protected的成员,但是无法访问private的成员。和private类似的,protected在外部都不允许被访问。


edit
play_arrow

brightness_4
// C++ program to demonstrate
// protected access modifier
#include <bits/stdc++.h>
using namespace std;

// base class
class Parent
{   
    // protected data members
    protected:
    int id_protected;

};

// sub class or derived class from public base class
class Child : public Parent
{
    public:
    void setId(int id)
    {

        // Child class is able to access the inherited 
        // protected data members of base class

        id_protected = id;

    }

    void displayId()
    {
        cout << "id_protected is: " << id_protected << endl;
    }
};

// main function
int main() {

    Child obj1;

    // member function of the derived class can
    // access the protected data members of the base class

    obj1.setId(81);
    obj1.displayId();
    return 0;
}

//Output
id_protected is: 81

Tips

无法在派生类中重载

比如下面的例子

#include<iostream>
using namespace std;

class B {
    public:
    int f(int i) { cout << "f(int): "; return i+1; }
    // ...
};

class D : public B {
    public:
    double f(double d) { cout << "f(double): "; return d+1.3; }
    // ...
};

int main()
{
    D* pd = new D;

    cout << pd->f(2) << '\n';
    cout << pd->f(2.3) << '\n';
}

//Output
f(double): 3.3
f(double): 3.6

D和B之间没有重载发生。你调用了pd->f(),编译器就在D的名字域里找啊找,找到double f(double)后就调用它了。编译器懒得再到B的名字域里去看看有没有哪个函数更符合要求。
如果一定需要跨域重载,则把哪些函数弄到同一个域中即可

class D : public B {
    public:
    using B::f;    // make every f from B available
    double f(double d) { cout << "f(double): "; return d+1.3; }
    // ...
};

//Output
f(int): 3
f(double): 3.6

因为D中的那句 using B::f 明确告诉编译器,要把B域中的f引入当前域,请编译器“一视同仁”。