首页 > 代码库 > 类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类
类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类
常量的基本类型转换,例如:int num(10.8),这种方式是隐式转换。
通过函数的构造函数实现转换。
类类转换函数,当构造函数不能将类型转换成基本类型时。所以就有了类类转换函数,通过这种方式。
案例:
#include <iostream> class fushu { public: //通过加explicit的这种方式避免隐式转换,避免引发歧义 explicit fushu(int num) { x = num; y = num; } void print() { std::cout << x << "+" << y << std::endl; } //下面对这个声进行明实现,重载int,这里是类型转换函数 operator int(); //不支持友元,仅仅支持成员函数 operator double() { return (double)(x + y); } protected: private: int x; int y; }; //下面是:类类之间的转换函数 fushu::operator int() { return x * y; } void main() { int num(100.9); fushu fushu1(num);//构造函数 fushu1.print(); //下满如果不带(int)将报错误提示 //类型转换可以把一个自定义类型当作基本数据类型来计算 int data = http://www.mamicode.com/(int)fushu1 + 10;//这一句的运行结果是:10000+10>4.类与类之间的类型转换
#include<iostream> class mianji { public: //通过友元,让fushu这个类可以调用这两个类的变量 friend class fushu; mianji() { this->cx = 0; this->cy = 0; } void setxy(int a,int b) { this->cx = a; this->cy = b; } private: int cx; int cy; }; class fushu { public: //友元可以访问私有变量 friend class mianji; fushu(mianji mianji1) { this->x = mianji1.cx; this->y = mianji1.cy; } void print() { std::cout << x << "+" << y << std::endl; } //使用operator+类的方式进行转换,类与类之间的类型转换 operator mianji() { mianji temp; temp.cx = x; temp.cy = y; return temp; } private: int x; int y; }; void main() { mianji mianji1; //这里调用了 //这里调用了fushu的有参构造函数 fushu fushu1 = (fushu)mianji1; fushu1.print(); //结果:0+0 fushu fushu2(mianji1);//调用了构造函数 fushu2.print(); //结果:0+0 mianji mianji2; //设置x,y的值 mianji2.setxy(10, 20); fushu1 = mianji2; fushu1.print(); //结果:10+20 std::cin.get(); }5.类和类之间的关系:
案例:
#include "mainwindow.h" #include <QApplication> #include<stdlib.h> //第一种关系,某一个类作为某一个类的部件 class mywindow { public: MainWindow w;//这时一种包含关系 }; class show { public: //部分的使用一个类,调用一个类 void showwindow(MainWindow & w) { w.show(); } }; //继承是通过加上:的方式实现 class newwindow:public MainWindow { public: //增强一个功能 void run(char *str) { system(str); } }; //测试继承 int mainA(int argc, char *argv[]) { QApplication a(argc, argv); newwindow new1; new1.show(); //运行的结果是显示了计算器窗口 new1.run("calc"); return a.exec(); } //通过包含的方式进行调用一个类 int main(int argc,char *argv[]) { QApplication a(argc,argv); mywindow my1; show show1; show1.showwindow(my1.w); return a.exec(); }6.继承之间的关系
A:共有(public)继承à可以无限传承,原来是共有的public继承之后仍然共有,私有的还是私有的。
B:私有(private)继承,只能继承一代,一代之后不可以继承了。不管父类里共有的还是私有的,都变成私有的了。
C:保护(protected)继承,共有成员全部变成了保护成员,保护成员不发生变化,可以无限传承。
创建三个类来描述这三种关系:
创建人类,代码如下:
头文件ren.h:
#pragma once class ren { public: ren(); ~ren(); long long selfnum; private: char *name; bool isman; protected: int money; int house; }; //设计一个类,可以无限传承美德,私有资产 //公有继承 ->无限传承,公有,保护不发生 70% //只能继承一代, //私有继承 ->传一代就断了,公有,私有都变成私有 //保护继承 //保护继承->公有成员全部变成保护成员 保护成员不发生变化,可以无限传承 ren.cpp #include "ren.h" ren::ren() { } ren::~ren() { }创建月光族
yueguang.h
#pragma once #include "ren.h" class yueguang:public ren //这里用月光族来模拟共有的特征 { public: yueguang(); ~yueguang(); }; yueguang.cpp #include "yueguang.h" yueguang::yueguang() { } yueguang::~yueguang() { }创建啃老族(父类的东西都变成自己的了,并且子辈没有东西):
kenlao.h
#pragma once #include "ren.h" class kenlao:private ren //模拟私有继承 { public: kenlao(); ~kenlao(); }; kenlao.cpp #include "kenlao.h" kenlao::kenlao() { } kenlao::~kenlao() { }模拟可传承的特征:
chuancheng.h
#pragma once #include "ren.h" class chuancheng:protected ren //模拟可供传承的类 { public: chuancheng(); ~chuancheng(); }; chuancheng.cpp #include "chuancheng.h" chuancheng::chuancheng() { } chuancheng::~chuancheng() { }7. //子类的内部可以访问父类的被保护的num,通过::num的方式进行调用
//此外还可以通过这种方式访问父类的方法。如果不写这个就是调用本类的方法
std::cout <<(this->coder::num) << std::endl;
通过另外一个案例说明继承的三种关系:
coder.h
#pragma once #include<iostream> //加了这一句之后std::cout才可以用 class coder { private: char *str; public: coder(); ~coder(); void girlfriend(); void coding(); protected: int num; }; coder.cpp #include "coder.h" coder::coder() { std::cout << "coder create" << std::endl; str = "锄禾日当午"; num = 100; } coder::~coder() { std::cout << "coder delete" << std::endl; } void coder::girlfriend() { std::cout << "一般都会写代码,可以创建一个对象,可是没有对象" << std::endl; } void coder::coding() { std::cout << "加班加点熬夜" << std::endl; }公有继承
cppcoder.h
#pragma once #include "coder.h" //使用public继承的时候 //父类的私有成员,不可以访问 //父类的保护成员,共有成员都可以访问 //共有继承,不影响保护成员,共有成员属性变化 class cppcoder:public coder { public: cppcoder(); ~cppcoder(); void coding(); void ui(); }; cppcoder.cpp #include "cppcoder.h" cppcoder::cppcoder() { std::cout << "cpp coder create" << std::endl; } cppcoder::~cppcoder() { std::cout << " cpp coder delete" << std::endl; } void cppcoder::ui() { std::cout << "QT真蛋疼" << std::endl; //子类的内部可以访问父类的被保护的num,通过::num的方式进行调用 //此外还可以通过这种方式访问父类的方法。如果不写这个就是调用本类的方法 std::cout << (this->coder::num) << std::endl; } void cppcoder::coding() { std::cout << "CPP真蛋疼" << std::endl; } 保护继承: ccoder.h #pragma once #include "coder.h" //父类的私有成员,不可以被继承 //父类的保护成员,共有成员内部可以访问 //protected继承的时候:保护成员,共有成员都会变成保护成员 class ccoder:protected coder { public: ccoder(); ~ccoder(); }; ccoder.cpp #include "ccoder.h" ccoder::ccoder() { } ccoder::~ccoder() { } 私有继承 javacoder.h #pragma once #include "coder.h" //父类的私有成员,不可以访问 //使用private继承之后,父类的保护成员,共有成员内部可以访问 //私有继承,共有成员,保护成员都变成私有成员 class javacoder:private coder { public: javacoder(); ~javacoder(); }; javacoder.cpp #include "javacoder.h" javacoder::javacoder() { //父类的被进程的变量可以在子类中可以访问,类外不可以被访问 this->num = 100; } javacoder::~javacoder() { } 主函数 #include<iostream> #include "coder.h" #include "cppcoder.h" #include "javacoder.h" void main1() { //通过new关键字创建一个类的指针 javacoder *pjava = new javacoder; //这时候的结果是:coder create,说明要调用父类的构造函数 std::cin.get(); } void main2() { cppcoder *ptansheng = new cppcoder; coder *pcode = new coder; ptansheng->ui(); std::cin.get(); //运行结果: //coder create //cpp coder create //coder create //QT真蛋疼 //100 } void main3() { //父类的指针,接受子类指针的地址 coder *pcode = new cppcoder; pcode->coding(); //通过reinterpret_cast进行类型转换 cppcoder *pcppcoder = reinterpret_cast<cppcoder *>(pcode); pcppcoder->coding(); //通过下面的方式实现获得指针类型 std::cout << typeid(pcode).name() << std::endl; std::cout << typeid(pcppcoder).name() << std::endl; std::cin.get(); //运行结果: //coder create //cpp coder create //加班加点熬夜 //CPP真蛋疼 //class coder * //class cppcoder * } void main() { cppcoder *ptansheng = new cppcoder; ptansheng->girlfriend(); ptansheng->ui(); //当子类与父类中函数同名的时候,会覆盖父类中的函数 ptansheng->coding(); //每一个子类都会生成一个默认的父类对象 //调用父类的同名方法可以通过下面的方式实现 ptansheng->coder::coding(); delete ptansheng; std::cin.get(); //运行结果: //coder create //cpp coder create //一般都会写代码,可以创建一个对象,可是没有对象 //QT真蛋疼 //100 //CPP真蛋疼 //加班加点熬夜 // cpp coder delete //coder delete }8.子类父类重名问题
#include<iostream> class father { public: int num; void print() { std::cout << num << std::endl; } father() { num = 99; } }; class son :public father { public: int num; void print() { std::cout << num << std::endl; } //子类覆盖父类 son() { num = 89; } }; void main() { son *pson = new son; pson->print(); //第一种方式调用父类中的方法 pson->father::print(); //第二种方式调用父类中的方法,将子类转换强转成为父类的指针 father *p = reinterpret_cast<father *>(pson); p->print(); std::cin.get(); } 运行结果: 89 99 999.基类的初始化
#include<iostream> class myclass { public: myclass() :x(0) { //x = 0; std::cout << "myclass init without num" << std::endl; } myclass(int num) :x(num) { //x = num; std::cout << "myclass init with num" << std::endl; } protected: private: int x; }; class myziclass :public myclass { public: myziclass() { std::cout << "myziclass init without num" << std::endl; } //第一个初始化的是父类,第二个,第三个是初始化本类的x,y myziclass(int num) :myclass(num), x(num + 1), y(num + 2) { std::cout << "myziclass init with num" << std::endl; } int x; int y; }; void main() { //指定构造函数 myziclass *p = new myziclass(10); std::cin.get(); }10.简单单继承的案例
#include <iostream> #include<math.h> class dian { public: friend class xian; dian(int a, int b, int c) :x(a), y(b), z(c) { } void print() { std::cout << "x=" << x << ",y=" << y << ",z=" << z << std::endl; } private: int x; int y; int z; }; //继承没有意义,包含 class xian { public: xian(dian dianx, dian diany) :dian1(dianx), dian2(diany) { } double getlength() { double length = 0; length = sqrt((dian1.x - dian2.x)*(dian1.x - dian2.x) + (dian1.y - dian2.y)*(dian1.y - dian2.y) + (dian1.z - dian2.z)*(dian1.z - dian2.z)); return length; } dian dian1; dian dian2; protected: private: }; class yuan :public xian { public: yuan(dian dianx, dian diany) :xian(dianx, diany) { } double getmianji() { return 3.1415926* (this->getlength())*(this->getlength()); } double zhouchang() { return 3.1415926 * 2 * (this->getlength()); } }; class qiu :public yuan { public: qiu(dian dian1, dian dian2) :yuan(dian1, dian2) { } double getmianji() { return 3.1415926* (this->getlength())*(this->getlength()) * 4; } double gettiji() { return 4 / 3.0*3.1415926* (this->getlength())* (this->getlength())* (this->getlength()); } }; void main() { dian dian1(0, 0, 1); dian dian2(0, 0, 6); dian1.print(); dian2.print(); xian xian1(dian1, dian2); std::cout << xian1.getlength() << std::endl; yuan yuan1(dian1, dian2); std::cout << yuan1.getmianji() << std::endl; std::cout << yuan1.zhouchang() << std::endl; qiu qiu1(dian1, dian2); std::cout << qiu1.gettiji() << std::endl; std::cout << qiu1.getmianji() << std::endl; std::cin.get(); }11.继承与静态变量
#include<iostream> class myclass { public: int data; static int num;//声明静态变量存在 myclass() { num++;//共享,统计对象的数目 } static void print() { //this->data;//静态函数无法使用this指针 //data = http://www.mamicode.com/10;>12.继承QT中的QLabel,并且增强其功能,创建一个QTGUI项目,修改main.cpp.
#include<QApplication> #include<QLabel> #include<stdlib.h> class mylabel:public QLabel { public: mylabel(char *str):QLabel(str) { } void run(char *str) { system(str); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); mylabel my1("12345ABC"); my1.show(); my1.run("notepad"); return a.exec(); }13:多继承,将很多东西的东西集成在一起,多继承案例如下:
#include <iostream> #include<stdlib.h> class A{}; class B{}; class myclass1 { public: void run(char *str) { system(str); } myclass1() { std::cout << "myclass1 is create" << std::endl; } ~myclass1() { std::cout << "myclass1 is delete" << std::endl; } }; class myclass2 { public: int add(int a, int b) { return a + b; } myclass2() { std::cout << "myclass2 is create" << std::endl; } ~myclass2() { std::cout << "myclass2 is delete" << std::endl; } }; class myclass :public myclass1, public myclass2, public A, public B { public: void print(char *str) { std::cout << str << std::endl; } myclass() { std::cout << "myclass is create" << std::endl; } ~myclass() { std::cout << "myclass is delete" << std::endl; } }; void main() { myclass *pmy1 = new myclass; delete pmy1; myclass my1; my1.run("tasklist"); my1.myclass1::run("ipconfig"); std::cout << my1.add(10, 20) << std::endl; std::cout << my1.myclass2::add(19, 20) << std::endl; my1.print("12345"); std::cin.get(); }14.为了在创建类的时候不多次创建父类,使用虚基类技术,也就是说加上virtual关键字,案例如下:
#include<iostream> class obj { public: int num; obj(int data) :num(data) { std::cout << "obj create\n"; } obj() { num = 0; std::cout << "obj create\n"; } ~obj() { std::cout << "obj delete\n"; } }; //下面使用了virtual(虚基类的) class Aobj :virtual public obj { public: Aobj(int data) :obj(data) { std::cout << "Aobj create\n"; } ~Aobj() { std::cout << "Aobj delete\n"; } }; //多个类公共继承一个类的时候,为了避免重复生成父类,加上virtual class Bobj : virtual public obj { public: Bobj(int data) :obj(data) { std::cout << "Bobj create\n"; } ~Bobj() { std::cout << "Bobj delete\n"; } }; class ABobj :public Aobj, public Bobj { public: ABobj(int x, int y) :Aobj(x), Bobj(y) { std::cout << "ABobj create\n"; } ABobj(int z) :Aobj(z), Bobj(z) { std::cout << "ABobj create\n"; } ~ABobj() { std::cout << "ABobj delete\n"; } }; void main() { ABobj *p = new ABobj(10); std::cout << p->Aobj::obj::num << "\n"; std::cout << p->Bobj::obj::num << "\n"; delete p; std::cin.get(); }15:QT中的多继承实现
#include "mainwindow.h" #include <QApplication> #include <QPushButton> #include <QLabel> class zajiao :public MainWindow,public QLabel,public QPushButton { public: zajiao(char *str):QLabel(str),QPushButton(str) { this->MainWindow::setWindowTitle(str); } ~zajiao() {} }; int main(int argc, char *argv[]) { QApplication a(argc, argv); zajiao zajiao1("ABCDEF12345"); zajiao1.QPushButton::show(); zajiao1.QPushButton::move(0,0); zajiao1.QLabel::show(); zajiao1.MainWindow::show(); return a.exec(); }
类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类