类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类
常量的基本類型轉換,例如:int num(10.8),這種方式是隱式轉換。
通過函數的構造函數實現轉換。
類類轉換函數,當構造函數不能將類型轉換成基本類型時。所以就有了類類轉換函數,通過這種方式。
案例:
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+0fushu fushu2(mianji1);//調用了構造函數fushu2.print(); //結果:0+0mianji mianji2;//設置x,y的值mianji2.setxy(10, 20);fushu1 = mianji2;fushu1.print(); //結果:10+20std::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:
創建月光族
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
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,ymyziclass(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(); }
?
總結
以上是生活随笔為你收集整理的类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拷贝构造,深度拷贝,关于delete和d
- 下一篇: 商业服务网点超过300平方可以开餐饮吗