C++中的继承public, protected和private

C++中的继承public, protected和private

C++访问修饰符

继承是 C++ 面向对象编程的关键特性之一。它允许我们从现有类(基类)创建一个新类(派生类)。
派生类继承了基类的特性,并且可以拥有自己的附加特性。例如,

C++ 等面向对象编程语言的主要特性之一是数据隐藏。数据隐藏是指限制对类的数据成员的访问。这是为了防止其他函数和类篡改类数据。但是,让一些成员函数和成员数据可访问也很重要,以便可以间接操作隐藏的数据。C++ 的访问修饰符允许我们确定哪些类成员可以被其他类和函数访问,哪些不能。

public访问修饰符

public 关键字用于创建公共成员(数据和函数)。公共成员可以从程序的任何部分访问。

private访问修饰符

private 关键字用于创建私有成员(数据和函数)。私有成员只能从类内部访问。但是,友元类和友元函数可以访问私有成员。

protected 访问修饰符

protected 关键字用于创建受保护的成员(数据和函数)。可以在类内和派生类中访问受保护的成员。

C++友函数和友类

数据隐藏是面向对象编程的一个基本概念。它限制了来自类外部的私有成员的访问。同样,受保护的成员只能由派生类访问,而不能从外部访问。例如,

然而,C++ 中有一个叫做友元函数的特性,它打破了这个规则,允许我们从类外部访问成员函数。同样,还有一个朋友类。

C++的友函数

友元函数可以访问类的私有和受保护数据。我们在类的主体内使用friend关键字声明了一个friend函数。

类的友元函数在该类的范围之外定义,但它有权访问该类的所有私有成员和受保护成员。即使友元函数的原型出现在类定义中,友元函数也不是成员函数。

友元可以是函数、函数模板、成员函数、类或类模板,在这种情况下,整个类及其所有成员都是友元。


#include <iostream>

using namespace std;

class  complex {
public:
	complex(float real_v, float imag_v): real(real_v), imag(imag_v){};
	complex operator=(complex a) {real=a.real; imag=a.imag; return *this;};

// friend function
    friend complex operator+(complex a, complex b);
	friend void  show_complex(complex a);
private:
    float real;
    float imag;
};

complex operator+(complex a, complex b) {
	complex  c(0,0);
	c.real = a.real + b.real;
	c.imag = a.imag + b.imag;
	return c;
}

void  show_complex(complex a)
{
   cout << "(" << a.real << "," << a.imag << ")" << endl;
}

int main() {
	complex  num1(1.05, 20.6);
	complex  num2(10.0, 15.9);
	
	cout << "num1 : ";
	show_complex(num1);
	cout << "num2 : ";
	show_complex(num2);
	
	cout << "sum : ";
	complex sum = num1+num2;
	show_complex(sum);
	
    return 0;
}

输出结果

num1 : (1.05,20.6)
num2 : (10,15.9)
sum : (11.05,36.5)

C++的友类

在C++中,我们还可以使用友类。

当一个类被声明为友类时,友类的所有成员函数都成为友函数。

在下列的例子中,Algo是一个友类,我们可以从Algo内部访问Complex的所有成员。

但是,我们无法从Complex内部访问Algo的成员。这是因为 C++ 中的友关系是单向。


#include <iostream>

using namespace std;

class Algo;

class Complex {
private:
    int real;
	int imag;

// friend class declaration
    friend class Algo;

public:
    Complex()=delete;
	Complex(int rv, int iv): real(rv), imag(iv) {};
};

class Algo {
private:
    int numB;

public:
    Algo() : numB(1) {}
    
    int add(Complex obj) {
        return obj.real + numB;
    }

    int sub(Complex obj) {
        return obj.real - numB;
    }
};

int main() {
    Algo objAlgo;
	Complex objA(10, 35);
	Complex objB(5, 10);
	
    cout << " Sum: " << objAlgo.add(objA) << endl;
    cout << "diff: " << objAlgo.sub(objB) << endl;
	
    return 0;
}

输出结果

 Sum: 11
diff: 4

基类和派生类

一个类可以从多个类派生,这意味着,它可以从多个基类继承数据和函数。要定义派生类,我们使用类派生列表来指定基类。类派生列表命名一个或多个基类并具有以下形式

class derived-class: access-specifier base-class

其中 access-specifier 是 public、protected 或 private 之一,base-class 是先前定义的类的名称。如果未使用访问说明符,则默认情况下它是private。

存取控制和继承

派生类可以访问其基类的所有非私有成员。因此,派生类的成员函数不应访问的基类中的私有成员。

访问 public protected private
相同类
派生类
外部类

派生类继承所有基类方法,但下例的方法除外

  1. 基类的构造函数、析构函数和复制构造函数。
  2. 基类的重载运算符。
  3. 基类的友函数。

继承类型

当从基类派生类时,可以通过public、protected 或 private来继承基类。继承的类型由上面解释的访问说明符指定。

我们很少使用受保护或私有继承,但通常使用公共继承。在使用不同类型的继承时,遵守下列规则

  1. public 公共继承 - 使用public派生基类时,基类的公共成员(public)成为派生类的公共成员(public),基类的受保护成员(protected)成为派生类的受保护成员(protected),基类的私有成员不能直接从派生类访问,但可以通过调用基类的公共成员和受保护成员来访问。
  2. protected 受保护的继承 - 使用protected派生基类时,基类的公共成员(public)和受保护成员(protected)成为派生类的受保护成员(protected)。
  3. private 私有继承 - 使用private派生基类时,基类的公共成员和受保护成员成为派生类的私有成员(private)。
上一篇:普通大专生:Java工作难找,想问问那些拿到大厂offer的大专生


下一篇:设计模式系列----责任链模式理解