尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

C++运算符重载与多继承及二义性详解

C++运算符重载与多继承及二义性详解 1.类外运算符重载123456789101112131415161718192021222324252627282930313233343536classPoint {private:intx,y;public:// 系统C源码大量使用此方式 :x(x), y(y)Point(intx,inty) :x(x), y(y) {}// set get 函数voidsetX(intx) {this-x x;}voidsetY(inty) {this-y y;}intgetX() {returnthis-x;}intgetY() {returnthis-y;}};/*类外运算符重载* 在真实开发过程中基本上都是写在类的里面的外部是不能获取内部的私有成员的* */Point operator (Point point1,Point point2){intx point1.getX() point2.getX();inty point1.getY() point2.getY();Point res(x, y);returnres;}intmain(){Point pointA(10,20);Point pointB(10,20);Point pointCpointApointB;cout pointC.getX() , pointC.getY() endl;}日志输出20 , 40两个对象做法运算就是执行了运算符重载函数2.类内部运算符号重载1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374classPoint {private:intx,y;public:Point(){}// 系统C源码大量使用此方式 :x(x), y(y)Point(intx,inty) :x(x), y(y) {}// set get 函数voidsetX(intx) {this-x x;}voidsetY(inty) {this-y y;}intgetX() {returnthis-x;}intgetY() {returnthis-y;}/** 常量引用不允许修改只读模式* 性能的提高如果没有 运行 构建新的副本会浪费性能* 如果增加了 引用是给这块内存空间取一个别名而已* */Point operator (constPoint point){intxthis-xpoint.x;intythis-ypoint.y;returnPoint(x,y);}Point operator - (constPoint point){intxthis-x-point.x;intythis-y-point.y;returnPoint(x,y);}voidoperator () {// 对象this-x this-x 1;this-y this-y 1;}voidoperator (int) {// 对象this-x this-x 1;this-y this-y 1;}/*重载 输出运算符号* istream 输入 系统的* ostream 输出 系统的* *//* friend void operator (ostream _START,Point point){_START 开始输出 point.x : point.y 结束了 endl;}*//*多个 连着写 */friendostream operator (ostream _START,Point point){_START 开始输出 point.x : point.y 结束了 endl;return_START;}// istream 输入 系统的friendistream operator (istream _START, Point point) {// 接收用户的输入把输入的信息_START point.x point.y;return_START;}};intmain(){Point pointA(30,50);Point pointB(10,20);// Point pointCpointA-pointB;pointA;// cout pointA.getX() , pointA.getY() endl;cout pointA pointB endl;// 多个的Point pointC;cin pointC;// 是我们自己重载的哦cout 你输入的是 pointC.getX() endl;cout 你输入的是 pointC.getY() endl;}类内部运算符重载允许访问私有变量传入的参数是常量引用const 表示不可更改 可以提升性能只会有一个变量别名不加会拷贝一份浪费内存。 重载需要加friend 友元函数来进行重载ostream _START表示输出istream _START表示输入3.[] 运算符号重载12345678910111213141516171819202122232425262728293031323334353637classArrayClass {private:intsize 0 ;// 大小 开发过程中给size赋默认值不然可能会出现无穷大的问题int* arrayValue;// 数组存放 int 类型的很多值public:ArrayClass(){/*指针类型必须分配空间*/arrayValuestatic_castint*(malloc(sizeof(int*) * 10));}voidset(intindex,intvalue) {arrayValue[index] value;// []目前不是我的size1;}intgetSize() {// size成员的目标是为了循环可以遍历returnthis-size;}// 运算符重载 [index]intoperator[](intindex) {returnthis-arrayValue[index];// 系统的}};// 输出容器的内容voidprintfArryClass(ArrayClass arrayClass) {cout arrayClass.getSize() endl;for(inti 0; i arrayClass.getSize(); i) {cout arrayClass[i] endl;// []是我们自己的 重载符号}}intmain(){ArrayClass arrayClass;// 栈区 实例出来的对象是在堆区了arrayClass.set(0, 100);arrayClass.set(1, 200);arrayClass.set(2, 300);arrayClass.set(3, 400);arrayClass.set(4, 500);printfArryClass(arrayClass);}4.c继承1234567891011121314151617181920212223242526classPerson {public:char*name;intage;public:Person(char*name,intage) : name(name) {this-age age;cout Person 构造函数 endl;}voidprint() {cout this-name , this-age endl;}};classStudent :publicPerson {private:char* course;public:Student(char* name,intage,char* course) : Person(name, age) , course(course) {cout Student 构造函数 endl;}voidtest() {cout name endl;cout age endl;print();}};默认是 隐式代码 : private Person私有继承在子类里面是可以访问父类的成员但是在类的外面不行必须公开继承才可以访问父类的成员先执行父类的构造函数再执行子类的构造函数5.多继承12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455classBaseActivity1 {public:voidonCreate() {cout BaseActivity1 onCreate endl;}voidonStart() {cout BaseActivity1 onStart endl;}voidshow() {cout BaseActivity1 show endl;}};classBaseActivity2 {public:voidonCreate() {cout BaseActivity2 onCreate endl;}voidonStart() {cout BaseActivity2 onStart endl;}voidshow() {cout BaseActivity2 show endl;}};// 子类 继承 二个父类classMainActivity1 :publicBaseActivity1,publicBaseActivity2{public:voidonCreate() {cout MainActivity1 onCreate endl;}voidonStart() {cout MainActivity1 onStart endl;}voidshowSonInfo() {cout MainActivity1 showSonInfo endl;}// void show() {// cout MainActivity1 show endl;//}};intmain(){// 这个是优先寻找子类的函数因为特别明确没有问题还没有产生歧义二义性MainActivity1 mainActivity1;// 子类mainActivity1.onCreate();mainActivity1.onStart();mainActivity1.showSonInfo();// 不明确二义性歧义 /*request for member ‘show is ambiguous*/// mainActivity1.show();/*解决二义性 通过.来引出父类 然后再调用*/mainActivity1.BaseActivity3::show();mainActivity1.BaseActivity2::show();mainActivity1.BaseActivity1::show();// 解决方案二 子类上 重写父类的show函数mainActivity1.show();}c 允许多继承可能会出现二义性原则上是尽量避免二义性通过明确父类的方式解决二义性通过子类重写父类的方法规避二义性6.通过虚继承来解决二义性问题1234567891011121314151617181920212223242526272829303132333435// 祖父类classObject{public:intnumber;voidshow() {cout Object show run... endl;}};// 父类1classBaseActivity1 :virtualpublicObject {};// 父类2classBaseActivity2 :virtualpublicObject {};// 子类classSon :publicBaseActivity1,publicBaseActivity2 {};intmain(){Object object;BaseActivity1 baseActivity1;BaseActivity2 baseActivity2;Son son;object.number 100;baseActivity1.number 200;baseActivity2.number 300;son.number 400;object.show();baseActivity1.show();baseActivity2.show();son.show();cout object.number endl;cout baseActivity1.number endl;cout baseActivity2.number endl;cout son.number endl;}如果没有虚继承那么son对象访问number就会报二义性的问题同时访问show方法同样存在二义性问题由于在继承的时候添加了虚继承就能解决类似这样的问题虚继承的含义是将通过继承得来的number和show方法放置在另外一个统一空间上这样子类再访问的时候就不会出现二义性的问题了。
返回列表