c++中的访问说明符

之前一直知道protected是介于private和public两种访问权限的中间者,影响友元和派生类的访问权限。但是对于具体的细节还有一些疑惑的地方,今天仔细研究了一下c++primer上关于这一部分的解释,简单做个总结如下。

首先我们只考虑派生列表中使用的访问说明符,即所谓的派生访问说明符。对于基类B中的不管是public,private还是protected成员,我们有以下的原则。

1.如果派生类D以public方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员在D中的访问权限依然是public的,B中原来的protected成员在D中的访问权限依然是protected的,B中的private成员在D中依然是private的。

2.如果派生类D以protected方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员在D中的访问权限变为protected的,B中的原来的protected成员在D中的访问权限依然是protected的,B中的private成员在D中依然是private的

3.如果派生类D以private方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员和protected成员在D中的访问权限变为private的,B中的private成员在D中依然是private的

由以上的三条原则可以知道,所谓的派生访问说明符,并不会影响D的成员对B的成员的访问权限,因为这个权限已经由B中成员的访问说明符全权规定。试想,假设我们通过指定派生访问说明符,就可以通过派生类D来访问基类B中本不对外界开放的成员(特指private成员),那么基类中的访问说明权限还有什么意义呢?

进一步思考我们可以得出,派生访问说明符其实定义的是,在派生类将基类的成员继承过来之后,这些成员在D中的新的访问权限。具体地说就是,如果以public来继承B,则B中成员的访问权限在D中具有相同的访问权限;如果以protected来继承B,则D中成员的访问权限的变化是public成员改变成protected成员,其余不变;如果以private来继承B,则D中的所有成员都变成了private成员。如果按照成员在基类B中的访问权限来划分的话,private成员不管怎么被继承,依然是private的;protected在private继承下,会变成private成员;而public成员在protected继承下会变成protected成员,在private继承下会变成private成员。


然而有的时候我们想改变某些对象在派生类中的访问权限应该怎么办呢?比如某个成员在基类中是public或者protected的,我们通过private继承之后它们必然会具有private的访问权限,如果想让它们具有非private的权限可以吗?这可以通过using关键字来实现。比如下面的例子。

class B{
public:
std::size_t size() const{return n;}
protected:
sdt::size_t n;
};
class D:private B{
public:
using B::size;
protected:
using B::n;
}
我们通过using关键字,手动的指定了从基类继承来的成员的访问权限。

当然,protected访问说明符同时还影响友元对其的访问,因为这个比较简单,我们在这里就不讨论了。只需要注意一点就是,友元不具有反身性,当然更不具有传递性。我们只能对每一对具有友元关系的目标进行明确指定

以上是我对访问说明符的一些理解,写的比较啰嗦,但是个人感觉可以解释初学者大部分的疑惑了。欢迎大家指正批评。

### C++访问修饰符 `public`、`private` 和 `protected` 的用法 C++ 中的访问修饰符用于控制类成员(变量和方法)的可见性和可访问性。这些修饰符定义了哪些部分可以被其他类或程序访问,从而实现数据封装和隐藏的核心概念。 #### 1. 访问修饰符的作用范围 - **`private`**: 被标记为 `private` 的成员只能由该类本身的方法访问,无法从类外部直接访问[^1]。这是默认的访问级别,当未显式指定时,类中的成员会被视为 `private`[^2]。 - **`protected`**: 被标记为 `protected` 的成员可以在其所属类以及派生类中访问,但在类外仍然不可见[^1]。这种修饰符常用于设计基类与派生类之间的协作关系。 - **`public`**: 被标记为 `public` 的成员可以从任何地方访问,无论是类内部还是外部[^3]。它是最开放的访问级别。 #### 2. 默认访问修饰符 - 对于 **class** 定义,默认的访问修饰符是 `private`,即如果没有显式声明,所有成员都将是私有的[^2]。 - 对于 **struct** 定义,默认的访问修饰符是 `public`[^2]。 #### 3. 继承类型对访问权限的影响 继承方式会影响基类成员在派生类中的访问级别: | 基类成员 | 公有继承 (Public) | 受保护继承 (Protected) | 私有继承 (Private) | |----------|-------------------|-------------------------|--------------------| | Public | Public | Protected | Private | | Protected| Protected | Protected | Private | | Private | 不可访问 | 不可访问 | 不可访问 | 上述表格展示了不同继承模式下基类成员的访问权限变化情况[^1]。 #### 4. 示例代码展示 下面是一个简单的例子,演示如何使用不同的访问修饰符: ```cpp #include <iostream> using namespace std; // Base class with different access specifiers class Base { private: int privateVar; // Only accessible within the same class protected: int protectedVar; // Accessible by derived classes and itself public: int publicVar; // Accessible from anywhere Base() : privateVar(0), protectedVar(1), publicVar(2) {} void displayBaseVars() const { // Method to show all variables inside this class cout << "Private Var: " << privateVar << endl; cout << "Protected Var: " << protectedVar << endl; cout << "Public Var: " << publicVar << endl; } }; // Derived class demonstrating inheritance effects class Derived : public Base { public: void displayDerivedVars() const { // Cannot directly access 'privateVar' here, even though it's inherited. cout << "Protected Var: " << protectedVar << endl; // OK because of protection level cout << "Public Var: " << publicVar << endl; // Also OK due to being public } }; int main() { Base b; b.displayBaseVars(); // Can call method that accesses internal vars. // Directly accessing members outside their allowed scope will fail at compile time: // cout << b.privateVar; // Error: inaccessible member declared private in class ‘Base’ // cout << b.protectedVar; // Same error as above cout << "\nAccessing via derived class:\n"; Derived d; d.displayDerivedVars(); return 0; } ``` 此示例说明了各种访问修饰符的行为差异,并验证了它们对外部世界和其他类的具体影响。 --- 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值