|
上一篇文章我们介绍了c++中类的继承学习总结;今天我们继续来分享c++中类的继承中的访问级别的学习总结。 一、继承中的访问级别学习: 1、子类是否可以直接访问父类的私用成员吗? 从面向对象理论角度来看:
从c++的语法角度看:
代码示例: #include <iostream>#include <string> using namespace std; class Parent { private: int mv; public: Parent() { mv = 100; } int value() { return mv; } }; class Child : public Parent { public: int addValue(int v) { mv = mv + v; // 如何访问父类的非公有成员 } }; int main() { return 0; } 输出结果: root@txp-virtual-machine:/home/txp# g++ test.cpptest.cpp: In member function ‘int Child::addValue(int)’: test.cpp:9:9: error: ‘int Parent::mv’ is private int mv; ^ test.cpp:27:9: error: within this context mv = mv + v; // 如何访问父类的非公有成员 ^ test.cpp:9:9: error: ‘int Parent::mv’ is private int mv; ^ test.cpp:27:14: error: within this context mv = mv + v; // 如何访问父类的非公有成员 ^ 注解:我们可以看到子类不能直接访问到父类里面的属性 2、继承中的访问级别关系
-- 修饰的成员可以被子类直接访问 代码实现 #include <iostream>#include <string> using namespace std; class Parent { protected: int mv; public: Parent() { mv = 100; } int value() { return mv; } }; class Child : public Parent { public: int addValue(int v) { mv = mv + v; } }; int main() { Parent p; cout << "p.mv = " << p.value() << endl; p.mv = 1000; // error Child c; cout << "c.mv = " << c.value() << endl; c.addValue(50); cout << "c.mv = " << c.value() << endl; c.mv = 10000; // error return 0; } 运行结果: root@txp-virtual-machine:/home/txp# g++ test.cpptest.cpp: In function ‘int main()’: test.cpp:9:9: error: ‘int Parent::mv’ is protected int mv; ^ test.cpp:37:8: error: within this context p.mv = 1000; // error ^ test.cpp:9:9: error: ‘int Parent::mv’ is protected int mv; ^ test.cpp:47:7: error: within this context c.mv = 10000; // error 注解:这里我们把父类的属性private修改成protect,这里我们注意到在子类里面的方法中是可以使用父类中的属性mv了,只不过在int main()函数中,使用父类和子类定义的对象,均不可以对父类中的属性mv进行访问,这一点要注意。 3、为什么面向对象中需要protect? 我们还是用生活中的例子来理解,每个人的个人隐私,是不能泄露的,也就是我们c++中的private关键字;而你身上穿的衣服,每个人都可以知道,也就是c++中的public关键字;最后我们的protect关键字,为啥c++中会需要它,我想还是跟生活中有关(所以说,面向对象的编程,非常贴近生活),比如说,家庭开会,有些事情就不能让外人知道,但是自己家人就可以知道,所以这跟protect关键字的用法非常像,也就是说,protect关键鉴于private和public之间。 4、定义类时访问级别的选择:
注解:从图中我们可以发现,当有发生继承关系时,就考虑使用protect关键字 5、组合和继承的综合运用
说明:Object这个类是被用来继承的;Line和Point两个类进行组合。 代码示例: #include <iostream>#include <string> #include <sstream> using namespace std; class Object { protected: string mName; string mInfo; public: Object() { mName = "Object"; mInfo = ""; } string name() { return mName; } string info() { return mInfo; } }; class Point : public Object { private: int mX; int mY; public: Point(int x = 0, int y = 0) { ostringstream s; mX = x; mY = y; mName = "Point"; s << "P(" << mX << ", " << mY << ")"; mInfo = s.str(); } int x() { return mX; } int y() { return mY; } }; class Line : public Object { private: Point mP1; Point mP2; public: Line(Point p1, Point p2) { ostringstream s; mP1 = p1; mP2 = p2; mName = "Line"; s << "Line from " << mP1.info() << " to " << mP2.info(); mInfo = s.str(); } Point begin() { return mP1; } Point end() { return mP2; } }; int main() { Object o; Point p(1, 2); Point pn(5, 6); Line l(p, pn); cout << o.name() << endl; cout << o.info() << endl; cout << endl; cout << p.name() << endl; cout << p.info() << endl; cout << endl; cout << l.name() << endl; cout << l.info() << endl; return 0; } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outObject Point P(1, 2) Line Line from P(1, 2) to P(5, 6) 二、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版