在C++中,继承是一种面向对象编程的核心机制,允许一个类(派生类)继承另一个类(基类)的属性和方法。通过继承,派生类可以复用基类的代码,并且可以扩展或修改基类的行为。C++支持三种继承方式:public继承、protected继承和private继承。每种继承方式对成员的访问权限和继承行为有不同的影响。
一、继承的基本语法
在C++中,继承的语法如下:
cpp
复制
class DerivedClassName : AccessSpecifier BaseClassName {

// 派生类的成员

};
DerivedClassName:派生类的名称。
AccessSpecifier:访问限定符,可以是public、protected或private。
BaseClassName:基类的名称。
二、继承方式
(一)public继承
public继承是最常用的继承方式。在这种继承方式下,基类的公共成员和保护成员在派生类中保持其原有的访问权限,而基类的私有成员则无法被派生类直接访问。
特点
公共成员:基类的公共成员在派生类中仍然是公共的,可以通过派生类的对象直接访问。
保护成员:基类的保护成员在派生类中仍然是保护的,可以在派生类的成员函数中访问,但不能通过派生类的对象直接访问。
私有成员:基类的私有成员在派生类中无法直接访问,但可以通过基类的公共或保护成员函数间接访问。
示例代码
cpp
复制
class Base {
public:

void publicFunction() {
    std::cout << "Base publicFunction" << std::endl;
}

protected:

void protectedFunction() {
    std::cout << "Base protectedFunction" << std::endl;
}

private:

void privateFunction() {
    std::cout << "Base privateFunction" << std::endl;
}

};

class Derived : public Base {
public:

void derivedFunction() {
    publicFunction(); // 可以访问基类的公共成员
    protectedFunction(); // 可以访问基类的保护成员
    // privateFunction(); // 无法访问基类的私有成员
}

};

int main() {

Derived obj;
obj.publicFunction(); // 可以访问基类的公共成员
// obj.protectedFunction(); // 无法直接访问基类的保护成员
obj.derivedFunction(); // 通过派生类的成员函数访问基类的保护成员
return 0;

}
(二)protected继承
protected继承与public继承类似,但在这种继承方式下,基类的公共成员和保护成员在派生类中都变为保护成员,而基类的私有成员仍然无法直接访问。
特点
公共成员:基类的公共成员在派生类中变为保护成员,不能通过派生类的对象直接访问,但可以在派生类的成员函数中访问。
保护成员:基类的保护成员在派生类中仍然是保护成员,可以在派生类的成员函数中访问,但不能通过派生类的对象直接访问。
私有成员:基类的私有成员在派生类中无法直接访问,但可以通过基类的公共或保护成员函数间接访问。
示例代码
cpp
复制
class Base {
public:

void publicFunction() {
    std::cout << "Base publicFunction" << std::endl;
}

protected:

void protectedFunction() {
    std::cout << "Base protectedFunction" << std::endl;
}

private:

void privateFunction() {
    std::cout << "Base privateFunction" << std::endl;
}

};

class Derived : protected Base {
public:

void derivedFunction() {
    publicFunction(); // 可以访问基类的公共成员,但它是保护的
    protectedFunction(); // 可以访问基类的保护成员
    // privateFunction(); // 无法访问基类的私有成员
}

};

int main() {

Derived obj;
// obj.publicFunction(); // 无法直接访问基类的公共成员
obj.derivedFunction(); // 通过派生类的成员函数访问基类的公共成员
return 0;

}
(三)private继承
private继承是最严格的继承方式。在这种继承方式下,基类的所有成员(无论是公共成员、保护成员还是私有成员)在派生类中都变为私有成员。派生类的外部代码无法直接访问基类的任何成员,只能通过派生类的成员函数间接访问。
特点
公共成员:基类的公共成员在派生类中变为私有成员,不能通过派生类的对象直接访问,只能在派生类的成员函数中访问。
保护成员:基类的保护成员在派生类中变为私有成员,不能通过派生类的对象直接访问,只能在派生类的成员函数中访问。
私有成员:基类的私有成员在派生类中仍然无法直接访问,但可以通过基类的公共或保护成员函数间接访问。
示例代码
cpp
复制
class Base {
public:

void publicFunction() {
    std::cout << "Base publicFunction" << std::endl;
}

protected:

void protectedFunction() {
    std::cout << "Base protectedFunction" << std::endl;
}

private:

void privateFunction() {
    std::cout << "Base privateFunction" << std::endl;
}

};

class Derived : private Base {
public:

void derivedFunction() {
    publicFunction(); // 可以访问基类的公共成员,但它是私有的
    protectedFunction(); // 可以访问基类的保护成员
    // privateFunction(); // 无法访问基类的私有成员
}

};

int main() {

Derived obj;
// obj.publicFunction(); // 无法直接访问基类的公共成员
obj.derivedFunction(); // 通过派生类的成员函数访问基类的公共成员
return 0;

}
三、继承方式的选择
选择哪种继承方式取决于具体的设计需求:
public继承:最常用,适用于“是一个”(is-a)关系,例如“Dog 是一种 Animal”。在这种情况下,派生类对象可以被视为基类对象,基类的公共接口可以被派生类继承和扩展。
protected继承:较少使用,适用于“受保护的实现”关系,例如“Derived 使用了 Base 的实现,但不希望外部代码直接访问基类的接口”。
private继承:用于实现“使用”关系,而不是“是一个”关系。在这种情况下,派生类只是内部使用了基类的实现,但不希望外部代码感知到这种关系。
四、构造函数和析构函数的调用顺序
在继承中,构造函数和析构函数的调用顺序非常重要:
构造函数的调用顺序:
先调用基类的构造函数。
再调用派生类的构造函数。
析构函数的调用顺序:
先调用派生类的析构函数。
再调用基类的析构函数。
示例代码
cpp
复制
class Base {
public:

Base() {
    std::cout << "Base constructor" << std::endl;
}
~Base() {
    std::cout << "Base destructor" << std::endl;
}

};

class Derived : public Base {
public:

Derived() {
    std::cout << "Derived constructor" << std::endl;
}
~Derived() {
    std::cout << "Derived destructor" << std::endl;
}

};

int main() {

Derived obj;
return 0;

}
输出
复制
Base constructor
Derived constructor
Derived destructor
Base destructor
五、总结
C++ 提供了三种继承方式:public继承、protected继承和private继承。每种继承方式对成员的访问权限和继承行为有不同的影响。选择合适的继承方式需要根据具体的设计需求来决定。同时,理解构造函数和析构函数的调用顺序对于正确管理对象的生命周期至关重要。


愤怒的小马驹
1 声望0 粉丝