-
常量的基本类型转换,例如: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 = (int)fushu1 + 10;//这一句的运行结果是:10000+10
std::cout << data << std::endl;
std::cin.get();
}
//转换有两种方式:1、赋值;2.使用()调用构造进行转换
void main2()
{
int num(100.9); //这里调用了int类型的构造
fushu fushu1(num); //构造函数
int data(fushu1);//转换,调用:fushu::operator int()
std::cout << data << std::endl;
//通过下面几句走类类转换函数(fushu::operator int())data2-->data5,下面几种方式得到到的结果都是10000
int data2 = fushu1;
std::cout << data2 << std::endl;
int data3 = (int)fushu1;
std::cout << data3 << std::endl;
int data4 = int(fushu1);
std::cout << data4 << std::endl;
int data5 = (int(fushu1));
std::cout << data5 << std::endl;
}
void main1()
{
//基本数据类型转换,这里是隐式类型与显式转换,是否带有类型转换符
int num(10.8);
//调用构造函数,调用explicit fushu(int num)这个构造函数
fushu fushu1 = (fushu)10.8;
//调用之后的结果是:10
fushu1.print();
//通过static_cast的方式进行类型转换,这种方式同样走了构造函数
fushu fushu2 = static_cast<fushu>(12.8);
fushu2.print(); //调用之后的结果是:10
fushu fushu3 = (fushu)10;//构造函数
//因为一个类不可能转换成为int类型的,所以找重载int的fushu::operator int()
int numA = fushu3; //这里调用之后的结果是100
std::cout << numA << std::endl;
std::cin.get();
}
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
99
9.基类的初始化
#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 = 10;
std::cout << num << std::endl;
}
};
int myclass::num = 0;//静态变量初始化
//private私有继承,无法传承到下一代
class ziclass :protected myclass
{
void run()
{
this->print();
this->num;
}
};
class sunclass :protected ziclass
{
void goandrun()
{
this->ziclass::myclass::print();
}
};
void main()
{
ziclass *p = new ziclass;
ziclass z1;
sunclass *ps = new sunclass;
//int a;
//p->num; //这种方式同样不行,说明使用protected的之后,不可以再使用了
//p->print();
//p->myclass::num; //这里不能使用,因为ziclass使用protected从class继承
//p->myclass::print();
//ps->print();
//ps->ziclass::myclass::print();
std::cin.get();
}
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();
}