基本概念
C++类的继承有共有继承,保护继承和私有继承
以下是每种继承方式,以及对应的权限的变更
// C++ Implementation to show that a derived class
// doesn’t inherit access to private data members.
// However, it does inherit a full parent object
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A // 'private' is default for classes
{
// x is private
// y is private
// z is not accessible from D
};
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引入当前域,请编译器“一视同仁”。