C++非继承和类继承访问
机器学习入坑者 人气:2一、非继承时public、protected和private成员的访问属性
C++中保护成员使用protected进行声明,那么protected、public和private三者有什么区别呢?
先说结论:非继承时,protected
成员和private
成员没有任何区别,都是类内部可以直接访问它们、类外部的类对象不可访问它们、类内部的类对象可以访问它们;相比之下,public成员在类内部、类外部的类对象、类内部的类对象中都是可直接访问的。
下面定 义的Bird类:
class Bird { public: Bird() { eat(); // 正确,类内可以访问保护成员 }; protected: void eat() { printf("Bird eating \n"); } };
上述代码表明,类内是可以直接访问protected成员的,下面来看类外部的类对象:
int main() { Bird bird(); bird.eat(); // 错误,protected成员类外部对象不可访问 }
上述代码表明,类外部类对象是不能直接访问protected
成员的。
所以说,非继承时protected
成员和private
成员没有差别。它们真正展示出差异是在“基类和子类的继承”时,具体分析留在后面日志。
重点:上述分析强调了“类外部的类对象和类内部的类对象”是不同的(类内部类对象是指:Bird类的复制构造函数就使用Bird类对象的引用可以访问其私有成员和保护成员)。因此,才要特殊指明“类外部的类对象不能访问protected和private成员,类内部的类对象可以访问其protected和private成员”。
二、C++类继承过程中访问控制
在子类继承父类的过程中,子类可以指定以何种方式继承父类:public
继承、protected
继承和private
继承,这个过程可以称为“访问控制”。
在学习访问控制之前,需要知道类含有三种成员:public
成员、protected
成员、private
成员。在非继承的情况下,这三种成员的访问属性是不同的:public成员在类内部和外部均可被直接访问;protected和private成员均可以被类内部和类内部的类对象访问,均不能被类外部的类对象访问。为了便于自己记忆,称这个规则为“非继承时三种成员的访问法则”
此知识点的复杂性在于继承方式有三种,每种继承方式又对应三种成员,所以一共是九种情况。
为此,采用表格形式记录如下:
上表中“子类吸收后”表示父类成员在子类中是何种身份(身份指:public
或protected
或private
),也就是说不同的继承类型使得父类成员在子类中的身份不同。
比如:在protected继承类型中,父类中的public
成员对应在子类中为protected成员,此时子类内部(指成员函数和子类对象)可以访问该protected成员,但是子类外部的子类对象无法访问该成员。也就是说,通过protected类型的继承,该成员从父类中的public成员变为子类中的protected成员。
下面是public继承的例子,其中父类为Animal,子类为Duck:
class Animal { public: Animal(int age_) { age = age_; printf("Init Animal \n"); } void eat() { printf("Animal eating! \n"); } protected: void run() { printf("Animal Running! \n"); } private: int age=0; void showAge() { printf("Age is %d", age); } };
父类Animal中分别定义了public
类型的eat()
函数、protected类型的run()函数、private类型的showAge()函数。子类可以通过选择不同的继承方式,改变这几个函数在子类中的访问属性:
class Duck:public Animal { public: Duck(int age_) :Animal(age_) { printf("init Duck! \n"); run(); // 正确,子类内部可以访问基类public成员 eat(); // 正确,子类内部可以访问基类protected成员 showAge(); // 错误,子类内部不可访问基类的private成员 }; };
总结:
按照自己目前的理解,不管继承方式为public
、protected
和private
三种中的哪一个,父类的private成员对应到子类中均“不可直接访问”。此外,子类不继承父类的构造函数和析构函数。
疑惑:
书中所说的“不可直接访问”,目前自己并不知道如何间接访问,猜测可能是采用 “get” 和 “set” 方式进行间接访问。
加载全部内容