#includeusing namespace std; class stu { public: stu() :a(10),b(20),c(30){} void dump() { cout << a << b << c << endl; } private: int a;int b;int c; }; int main() { stu s; cout << sizeof(stu) << endl;cout << sizeof(s) << endl; return 0; } 终端输出: 12 12
依据在 C 语言中内存对齐的知识,可以知道,此结构数据类型的大小就是 12 了。我们 发现,成员函数并不占有结构的大小。
类成员函数实际的储存方式类成员函数只有一份(不论是类内还是类外),在对象调用过程中,传入对象的地址,具体可以表示为 this 指针
const in class 初始化列表的作用const 修饰类数据成员必须要初始化。const初始化,一种情况在类内,另一种是初始化列表
#includeusing namespace std; class stu { public: stu() //推荐使用初始化列表的方式 :a(100){} private: const int a; //const int a=100; //直接初始化也可以 }; int main() { stu s; return 0; }
引用在初始化时必须要赋值
#includeconst构成的重载using namespace std; class stu { public: stu(int &z) :_z(z){} //初始化列表是在类创建完成之前就完成的 //stu(int& z) //这是错误的,因为引用在初始化时要赋值 //{ // _z = z; //} private: int& _z; }; int main() { int a = 100; stu s(a); return 0; } 那么,在传参时可不可以写成 stu(int z),这是不可以的,如果这样写的话,传入的参数就会生成一个新的临时变量,使得int &z 的引用变成了这个临时变量的引用,而不是 a 的引用
#includeconst构成的成员函数重载using namespace std; int add(int& a, int& b) { return a + b; } int add (const int& a, const int& b) //参数类型不同 { return a + b; } int main() { int a = 1; int b = 3; cout << add(a, b) << endl; cout << add(1, 5) << endl; //调用第二个函数,因为1 5 均为常量不能被 int& 所接受 return 0; } 终端输出 4 6
const构成的重载函数:非const对象优先调用非const版本,const对象只能调用const版本
class A
{
public:
A(int x, int y)
:_x(x),_y(y)
{}
void foo() const
{
cout <<" foo() const"<< endl;
cout << _x << _y << endl;
}
void foo()
{
cout << " foo() " << endl;
cout << _x << _y << endl;
}
private:
int _x;
int _y;2
};
int main()
{
A a(3,2); //非const对象
a.foo();
return 0;
}
终端s: foo() const
const修饰类函数
- const修饰类函数成员,不可以修饰全局函数
- const修饰函数后,承诺本函数内不会发生改变成员数据的行为,并且被const修饰的函数只能调用被const调用的函数,这保证了成员不可被更改
- 类外定义的const成员函数,在定义和声明处都需要const修饰符
class A
{
void dis()const
{函数体}
};
const修饰对象
- const修饰的对象其内可以有非const的数据成员,但不可修改
- 只能调用 const 成员函数
#includestatic in classusing namespace std; class A { public: A(int x,int y):_x(x),_y(y){} void dis() const {} private: int _x; int _y; }; int main() { const A a(1,2); a.dis(); return 0; }
C++扩展了 static 在类中的语意,用于实现在同一个类,多个对象间数据共享,协调 行为的目的。静态变量有全局变量的优势,又不会像全变量一样被滥用。而这一类变量,即可以通 过类来管理,也可以通过类的静态函数来管理。 类的静态成员,属于类,也属于对象,但终归属于类
static data member语法规则:
声明: static 数据类型 成员变量 【类内部】
初始化:数据类型 类名::静态数据成员 = 初值 【类外部】
调用:类名::静态数据成员 【既可以通过对象也可以通类访问】
类对象.静态数据成员
//static 修饰数据成员需要初始化,不可以在类内初始化
//类外初始化,需要类名空间,且不需要static
//类的声明与实现分开的时候,初始化在 .cpp 文件中。如果初始化在 .h 文件中就会造成重定义,因为.h文件及被包含在.cpp文件中也被包含在主函数中,造成重定义
//static声明的数据成员不占对象的大小,存储在data段的 rw段。
//访问
class A
{
public:
int _m;
static int _share; //相当于声明
};
int A::_share = 100; //前面不能加static,语法规范,真正的定义
//不能写成 static int _share = 100
int main()
{
A a;
cout << a._share << endl;
cout << sizeof(a);
}
终端输出:
100
4
static的共享性,全局性优势
#includeusing namespace std; class University { public: University(string t,string l) :_tower(t),_lack(l){} static string _lib; void dis() { cout << _tower << " " << _lack << " " <<_lib << endl; } private: string _tower; string _lack; }; string University::_lib = ""; int main() { University pk("博雅塔", "未名湖"); University bs("电视塔", "太明湖"); University xdf("雷峰塔", "西湖"); pk._lib += "九阴真经"; pk.dis(); bs._lib += "中国挖掘机"; bs.dis(); xdf._lib += "英语"; xdf.dis(); return 0; } 终端输出: 博雅塔 未名湖 九阴真经 电视塔 太明湖 九阴真经中国挖掘机 雷峰塔 西湖 九阴真经中国挖掘机英语
但是这样写不具有封装性,因此作修改
#include访问using namespace std; class University { public: University(string t,string l) :_tower(t),_lack(l){} static string& getLib() //通过static函数访问 { return _lib; } void dis() { cout << _tower << " " << _lack << " " <<_lib << endl; } private: string _tower; string _lack; static string _lib; //私有 }; string University::_lib = ""; int main() { University pk("博雅塔", "未名湖"); University bs("电视塔", "太明湖"); University xdf("雷峰塔", "西湖"); pk.getLib() += "九阴真经"; pk.dis(); bs.getLib() += "中国挖掘机"; bs.dis(); xdf.getLib() += "英语"; xdf.dis(); return 0; }
类的静态成员即属于类也属于对象,但终归是属于类
#includeusing namespace std; class A { public: int _m; static int _share; }; int A::_share = 100; int main() { A a; cout << A::_share; //没有对象是可以通过命名空间的形式访问,说明_share属于类 cout << a._share< 在创建对象前,类的静态成员对象就已经完成了初始化并存放在data段
static修饰函数
- 目的是为了管理静态变量
- 在类内声明在类外定义(初始化),声明要加static定义不加static
- 静态成员函数只能访问静态的成员(数据成员和函数成员),不能访问非静态的成员,下面解释原因:
class A { public: static void manageA(); static void manageB(){} void foo(){} private: static int a; }; int A::a = 100; void manageA() { } int main() { A a; a.manageA(); a.manageB; A::manageA();A::manageB(); return 0; }在调用函数foo时,函数为了可以找到所要操作的对象会传入this指针。调用manageA()manageB()函数时,既可以使用对象也可以使用类来调用(本质都是使用类来调用),使用类调用是不用传入this指针的。静态成员函数中没有this指针,那么就没有资格访问非静态成员。非静态函数可以访问静态成员。静态成员函数只能访问静态数据成员。原因:非静态成员函数在调用时this指针被当作参数传进。而静态成员函数属于类,而不属于对象,没有this指针
排号的实现#include课堂实战 单例模式using namespace std; class Server { public: Server(char n) :_serverName(n){} void serverOne() { if (_openFlag && _lastServerIdx < _turnCount) { _lastServerIdx++; cout << "server " << _serverName << "server for " << _lastServerIdx << endl; if (_lastServerIdx >= _turnCount) _openFlag = false; } } static bool stillOpen() { return _openFlag; } static int& getTurn() { return _turnCount; } private: char _serverName; static int _turnCount; static bool _openFlag; static int _lastServerIdx; }; int Server::_turnCount = 0; bool Server::_openFlag = true; int Server::_lastServerIdx = 0; int main() { Server a('A'), b('B'); cout << "how many pople in the row" << endl; int num; cin >> num; for (int i = 0; i < num; i++) { cout << "idx = "<< ++Server::getTurn() << endl; } do { a.serverOne(); b.serverOne(); } while (Server::stillOpen()); return 0; } 一个类仅有一个实例的现像,称为单例模式
#includestatic constusing namespace std; class singleton { public: static singleton* getsingleton() //在类中自己创建 { if (ptr == nullptr) { singleton* ptr = new singleton; return ptr; } } static void freesingleton() //调用函数销毁 { if (ptr != nullptr) { delete ptr; ptr = nullptr; } } private: singleton(){} ~singleton(){} singleton(const singleton& another){} singleton& operator=(const singleton& another){} static singleton* ptr; }; singleton* ptr = nullptr; class A { public: A(){} void dis() { cout << arr << endl; } private: static const int arr = 100; //只有这一种初始化的方式 };point to class memberC++拓展了指针在类中的使用,使其可以只想类成员(数据成员和函数成员),这种行为是类层面的而不是对象层面的
#include语法:using namespace std; class Student { public: Student(string n,int nu):name(n),num(nu){} private: string name; int num; }; int main() { Student s("zhangsan", 100); Student* ps = &s; // //string* psn = &s.name; 这不可以,因为此行为破坏了封装,name不可访问 //下面要将的指针是指向类层面的指针,而不是指向对象 return 0; } 指向非静态数据成员的指针在定义时必须和类相关联,在使用时必须和具体的对象关 联。 由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对 象,然后,通过对象来引用指针所指向的成员。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyMkSHhz-1655359987346)(E:博客photoSnipaste_2022-05-17_15-59-18.png)]
#include应用using namespace std; class Student { public: Student(string n,int nu):name(n),num(nu){} void dis() { cout << name << endl; } string name; int num; }; int main() { Student s("zhangsan", 100);//通过对象访问 Student* ps = &s; //通过指向对象的指针访问 string Student::* psn = &Student::name; //定义指向类成员的指针 cout << s.*psn << endl; cout << ps->*psn << endl; void(Student:: * pdis)() = &Student::dis; //定义指向类函数的指针变量,此函数不能是静态函数 (s.*pdis)(); //在类对象中通过类指针调用函数 (ps->*pdis)(); return 0; } 终端输出: zhangsan zhangsan zhangsan zhangsan 统一接口:
#includeusing namespace std; struct Point { int add(int x, int y) { return x + y; } int sub(int x, int y) { return x - y; } int mul(int x, int y) { return x * y; } int div(int x, int y) { return x % y; } }; int oper(Point* pf, int (Point::* fd)(int, int), int x, int y) { return (pf->*fd)(x, y); } typedef int(Point::* PF)(int, int); //给类型 int (Point::*)(int , int)起别名PF int main() { Point*s = new Point; PF pf = &Point::add; cout< 更加隐蔽的接口:
#include本质:using namespace std; class Game { public: Game() { pf[0] = &Game::a; pf[1] = &Game::b; pf[2] = &Game::c; pf[3] = &Game::d; } void select(int i) { (this->*pf[i])(i); } private: void a(int idx) { cout << "idx = " << idx << endl; } void b(int idx) { cout << "idx = " << idx << endl; } void c(int idx) { cout << "idx = " << idx << endl; } void d(int idx) { cout << "idx = " << idx << endl; } enum num{n = 4}; void(Game::*pf[n])(int idx); }; int main() { Game game; game.select(2); game.select(0); } 指向类成员的指针,具有指针的形而不具体指针的实质,或者,确切意义上说,不指 是指针,而存放的是偏移量
指向类静态成员的指针语法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rsFhwZOu-1655359987348)(E:博客photoSnipaste_2022-05-19_10-44-28.png)]#includeusing namespace std; #include using namespace std; class A { public: static void dis(); static int data; }; void A::dis() { cout< day6 friend有元 引入: #includeusing namespace std; class sprite { public: int getlifeCount() { cout << lifeCount << endl; } void setlifeCount(int lb) { lifeCount = lb; } private: int lifeCount; }; void fight(sprite& fd) //全局函数 { fd.setlifeCount(fd.getlifeCount() - 20); cout << fd.getlifeCount(); } int main() { sprite a; fight(a); } 每次打精灵的时候都要大量调用getlifeCount函数和setlifeCount函数,这耗费了大量的压栈和出栈,效率低,如果fight函数可以直接操作对象中的私有成员就避免了多次调用set,get函数的开销,因此引入了友元函数,相当于类对外界的一个授权,授权访问私有成员的权限
#includewhy 有元using namespace std; class sprite { friend void fight(sprite& fd); //变为友元函数 public: int getlifeCount() { cout << lifeCount << endl; } void setlifeCount(int lb) { lifeCount = lb; } private: int lifeCount; }; void fight(sprite& fd) { fd.lifeCount -= 20; //友元函数直接操作私有成员 cout << fd.getlifeCount(); } int main() { sprite a; fight(a); } 采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员 函数一般定义为公有的,依此提供类与外界间的通信接口。 但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的 数据成员,这时可以将这些函数定义为该类的友元函数。除了友元函数外,还有友元类, 两者统称为友元。 友元的作用是提高了程序的运行效率(即减少了类型和安全性检查及调用的时间开销), 但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友 元类
声明为谁的有元就可以通过谁的对象访问谁的私有成员
友元函数: 全局函数作友元#include类函数作友元#include using namespace std; class Point { friend double getDistance(Point& p1, Point& p2); //位置并不重要 public: Point(int x = 0,int y = 0):_x(x),_y(y){} void dumpFormate() { cout << _x << " " << _y << endl; } private: double _x; double _y; }; double getDistance(Point& p1, Point& p2) { double dx = p1._x - p2._x; double dy = p1._y - p2._y; return sqrt(dx * dx + dy * dy); } int main() { int a = 2; double b = 2.3; Point p1(3, 4); Point p2(7, 8); cout << getDistance(p1,p2)<< endl; return 0; } 引入:
class Point { friend double managePoint::getDistance(Point& p1, Point& p2); //添加友元 public: Point(int x = 0,int y = 0):_x(x),_y(y){} void dumpFormate() { cout << _x << " " << _y << endl; } private: double _x; double _y; }; class managePoint { public: double getDistance(Point& p1, Point& p2); //声明 }; double managePoint::getDistance(Point& p1, Point& p2) //定义 { double dx = p1._x - p2._x; double dy = p1._y - p2._y; return sqrt(dx * dx + dy * dy); }编译错误:这里在添加友元函数时用到了managePoint::getDistance这个类函数,但是前面并没有定义这个类,更没有这个类函数
调转这两个类之后:
class managePoint { public: double getDistance(Point& p1, Point& p2); //声明 }; class Point { friend double managePoint::getDistance(Point& p1, Point& p2); //添加友元 public: Point(int x = 0,int y = 0):_x(x),_y(y){} void dumpFormate() { cout << _x << " " << _y << endl; } private: double _x; double _y; }; double managePoint::getDistance(Point& p1, Point& p2) //定义 { double dx = p1._x - p2._x; double dy = p1._y - p2._y; return sqrt(dx * dx + dy * dy); }在类managePoint中用到了 Point& 这属于类Point在managePoint之后,这就要用到前项声明了
前项声明:
- 不能定义对象
- 可以用于定义指向这个类型的指针或引用
- 用于声明(不是定义),作为形参类型或者函数的返回值类型
结果:
#include#include using namespace std; class Point; //前项声明 class managePoint { public: double getDistance(Point& p1, Point& p2); //声明 }; class Point { friend double managePoint::getDistance(Point& p1, Point& p2); //添加友元 public: Point(int x = 0,int y = 0):_x(x),_y(y){} void dumpFormate() { cout << _x << " " << _y << endl; } private: double _x; double _y; }; double managePoint::getDistance(Point& p1, Point& p2) //定义 { double dx = p1._x - p2._x; double dy = p1._y - p2._y; return sqrt(dx * dx + dy * dy); } int main() { int a = 2; double b = 2.3; Point p1(3, 4); Point p2(7, 8); managePoint ss; cout < 友元类 当希望一个类中所有成员函数均变为另一个类的私有成员时,可以将该类声明为另一类的友元类
声明class A { friend class B; public: ... private: ... };例子1:
#include#include using namespace std; class Point { friend class managePoint; //添加友元类,相当于对类mamagePOoint授权,使得类managePoint可以访问类Point的私有成员 public: Point(int x = 0, int y = 0) :_x(x), _y(y) {} void dumpFormate() { cout << _x << " " << _y << endl; } private: double _x; double _y; }; class managePoint { public: double getDistance(Point& p1, Point& p2) //定义 { double dx = p1._x - p2._x; double dy = p1._y - p2._y; return sqrt(dx * dx + dy * dy); } }; int main() { int a = 2; double b = 2.3; Point p1(3, 4); Point p2(7, 8); managePoint ss; cout << ss.getDistance(p1, p2) << endl; return 0; } 若将两个类互换位置,则编译错误,因为类managePoint中用到了类Point但类Point还没有定义也没有授权
例子2
#include#include using namespace std; class Point { friend class managePoint; public: Point(int x,int y):x_(x),y_(y){} private: float x_; float y_; }; class managePoint { public: float getDistancd(Point& p1, Point& p2); float getArea(Point& p1, Point& p2, Point& p3); }; float managePoint::getDistancd(Point& p1, Point& p2) { float dx = p1.x_ - p2.x_; float dy = p1.y_ - p2.y_; return sqrt(dx * dx + dy * dy); } float managePoint::getArea(Point& p1, Point& p2, Point& p3) { float d1 = getDistancd(p1, p2); float d2 = getDistancd(p1, p3); float d3 = getDistancd(p2, p3); float p = (d1 + d3 + d2); return sqrt(p * (p - d1)*(p - d2)*(p - d3)); } int main() { Point p1(2, 5); Point p2(8, 3); Point p3(12, 56); managePoint ms; cout< 注意:
运算符重载
- 友元不可继承
- 友元关系是单向的
- 友元关系不具有传递性
运算符重载的本质是函数重载。函数名即:operator + 符号
友元重载#include成员重载using namespace std; class complex { friend complex operator+(complex& c1, complex& c2); public: complex(float r = 0,float i = 0):real_(r),image_(i){} void dump() { cout << real_ << " ( " << image_ << " ) " << endl; } private: float real_; float image_; }; complex operator+(complex&c1,complex&c2) { complex ret; ret.real_ = c1.real_ + c2.real_; ret.image_ = c1.image_ + c2.image_; return ret; } int main() { complex a(1, 2); complex b(3.4); complex sum = a + b; sum.dump(); return 0; } #includeusing namespace std; class complex { public: complex(float r = 0,float i = 0):real_(r),image_(i){} void dump() { cout << real_ << " ( " << image_ << " ) " << endl; } complex operator+(complex&another) //此函数不可返回引用。函数返回值是会产生一个临时对象,而返回引用不会,既然是引用,那马就要考虑引用谁,如果引用的是函数内栈 //上创建的东西,那么当函数结束时此栈就会消失,自然不能做返回。这里在函数内新建了一个类对象,存在栈上显然不能返回引用 { complex ret; ret.real_ = this->real_ + another.real_; ret.image_ = this->image_ + another.image_; return ret; } complex& operator=(complex&another) { this->real_ = another.real_; this->image_ = another.image_; return *this; } private: float real_; float image_; }; int main() { complex a(1, 2); complex b(3,4); complex sum = a.operator+(b); // a + b, this指针的值为类对象a的地址 sum.dump(); return 0; } 对上面的代码进行优化
class complex { public: complex(float r = 0,float i = 0):real_(r),image_(i){} void dump() { cout << real_ << " ( " << image_ << " ) " << endl; } const complex operator+(const complex&another) //此函数不可返回引用。函数返回值是会产生一个临时对象,而返回引用不会,既然是引用,那马就要考虑引用谁,如果引用的是函数内栈 //上创建的东西,那么当函数结束时此栈就会消失,自然不能做返回。这里在函数内新建了一个类对象,存在栈上显然不能返回引用 { complex ret; ret.real_ = this->real_ + another.real_; ret.image_ = this->image_ + another.image_; return ret; } complex& operator=(const complex &another) { this->real_ = another.real_; this->image_ = another.image_; return *this; } private: float real_; float image_; };首先·对两对象传入的参数加上了const,因为两函数并没有改变传入对象的成员。又对 complex operator+(const complex&another) 前加了const表示,返回值不可更改,下面解释原因/
int a = 2, b = 3, c = 4; a = b = c; a + b + c; (a + b) = c; //不可以 a = (b + c);为了使对象和普通变量拥有一样的性质,让(a+b) = c无法通过,于是就在类函数operator+前加了const,使他不可被赋值
双目运算符重载的研究方法以 +=为例先有 int main() { int a=10,b=20,c=30 a+=b;b+=c; cout <<"a:"单目运算符的研究方式以 - 为例image_ += another.image_; } private: float real_; float image_; }; 先有: int main() { int a = 10, b = 20, c = 30; a += b += c; //将b+=c的返回值做参数 cout << "a:" << a << " b:" << b << " c:" << c << endl; } #include using namespace std; class complex { public: complex(int r = 0,int i = 0):real_(r),image_(i){} complex operator+=(const complex& another) { this->real_ += another.real_; this->image_ += another.image_; return *this; } void dump() { cout << real_ << " " << image_; } private: float real_; float image_; }; int main() { int a = 10, b = 20, c = 30; a += b += c; cout << "a:" << a << " b:" << b << " c:" << c << endl; complex aa(10, 0), bb(20, 0), cc(30, 0); aa += bb += cc; //相当于aa.operator+=(bb.operator+=(cc)),将bb.operator+=(cc)的返回值作为参数传入 //第一次重载函数完成后生成了临时对象并没有实际的内存,对临时对象的引用为常引用const aa.dump(); bb.dump(); cc.dump(); } 先有: int main() { int a = 10, b = 20, c = 30; (a += b) += c; cout << "a:" << a << " b:" << b << " c:" << c << endl; } 后有: complex& operator+=(const complex& another) //返回引用,若不返回引用:先完成(a + b)返回一个临时对象,之后再临时对象上加c ,之后临时对象销毁这样a上只加了b而没有加c { this->real_ += another.real_; this->image_ += another.image_; return *this; } 先有: int main() { int n = 5; cout << -n << endl;cout << n << endl; } 后有: class complex { public: complex(int r = 0,int i = 0):real_(r),image_(i){} complex operator-() { return complex(-real_, -image_); } void dump() { cout << real_ << " " << image_; } private: float real_; float image_; }; 先有: int n = 10; -n = 5; //error。说明不可被赋值 再有: const complex operator-() { return complex(-real_, -image_); } 先有: cout<<-(-n)<单目运算符 ++ 重载 先有: int main() { int a = 10; cout << ++a <流输入输出运算符重载 #includeusing namespace std; class Complex { public: Complex(float x=0, float y=0):_x(x),_y(y){} friend ostream & operator<<(ostream &os, const Complex & c); friend istream & operator>>(istream &is, Complex &c); //成员的话必须保证左值为该类的对象 private: float _x; float _y; }; ostream & operator<<(ostream &os, const Complex & c) { os<<"("< >(istream &is, Complex &c) { is>>c._x>>c._y; return is; } int main() { Complex c(2,3); cout< >c; cout< 也可以写为:
#includeusing namespace std; class Complex { public: Complex(float x=0, float y=0):_x(x),_y(y){} friend ostream & operator<<(ostream &os, const Complex & c) { os<<"("< >(istream &is, Complex &c) { is>>c._x>>c._y; return is; } //成员的话必须保证左值为该类的对象 private: float _x; float _y; }; int main() { Complex c(2,3); cout< >c; cout< user-Defined Type Cast 自定义类型强转 自定义类型转化构造函数 语法: class 目标类 { m(const 原类型 & 源对象的引用) { 更具需求完成转换 } } 目标:实现其他类型到本类型的额转化 原理:转换构造函数。是只有一个参数的构造函数,如有多个参数,只能称为构造函数,而不是转换函数。转换构造强调是一转一例子:#includeexplicit (显性)关键字using namespace std; class print2D { friend class print3D; public: print2D(int x = 0,int y = 0):x_(x),y_(y){} private: int x_; int y_; }; class print3D { public: print3D(int x = 0, int y = 0, int z = 0) :x_(x), y_(y),z_(z) {} //转化构造函数的本质也是构造函数 print3D(const print2D & d2) { this->x_ = d2.x_; this->y_ = d2.y_; this->z_ = rand() % 100; } void dumpFormate() { cout << "x: " << x_ << "y: " << y_ << "z: " << z_; } private: int x_; int y_; int z_; }; print3D convid(const print2D& d2) { //print3D d3(d2); //return d3; return print3D(d2); //这样会返回一个无名的类对象 } int main() { print2D d2(10,100); print3D d3; //d3 = d2; //第一种转化方式,相当于d3(d2) d3 = convid(d2); 用有名的类对象接收无名的类对象 d3.dumpFormate(); return 0; } 用于修饰构造函数
#include操作符函数转化 语法:using namespace std; class print2D { friend class print3D; public: print2D(int x = 0, int y = 0) :x_(x), y_(y) {} private: int x_; int y_; }; class print3D { public: print3D(int x = 0, int y = 0, int z = 0) :x_(x), y_(y), z_(z) {} explicit print3D(const print2D& d2) { this->x_ = d2.x_; this->y_ = d2.y_; this->z_ = rand() % 100; } void dumpFormate() { cout << "x: " << x_ << "y: " << y_ << "z: " << z_; } private: int x_; int y_; int z_; }; int main() { print2D d2(10, 100); //print3D d3; //d3(d2) //显示调用可以编过 // d3 = d2 //不行,编不过 print3D d3 = static_cast (d2); //必须加强转,因为构造函数被声明为explicit(显性的) d3.dumpFormate(); return 0; } class 源类 { operator 目标类(void) { return 目标类构造器(源类实参) } }例子:#includeoperator作类的转换函数#include using namespace std; class print3D { public: print3D(int x = 0, int y = 0, int z = 0) :x_(x), y_(y), z_(z) {} void dumpFormate() { cout << "x: " << x_ << "y: " << y_ << "z: " << z_; } private: int x_; int y_; int z_; }; class print2D { public: print2D(int x = 0, int y = 0) :x_(x), y_(y) {} operator print3D() { return print3D(this->x_, this->y_,rand() % 100); //相当于执行print3D的构造函数,后返回 } private: int x_; int y_; }; print3D convert(print2D& d2) { return print3D(d2); } int main() { print2D d2(10, 0); print3D d3(d2); //3种由d2 转换为 d3的方法 print3D d3 = d2; d3 = convert(d2); d3.dumpFormate(); return 0; }
- 转换函数必须是类方法
- 转换函数不能指定返回类型
- 转换函数不能有参数
operator 目标类(void) { return 目标类构造器(源类实参) //其实是调用了目标类的构造器 }



