c++常用知识点3
来源:互联网 发布:sql having count(*) 编辑:程序博客网 时间:2024/06/17 06:33
1.初始化列表
构造函数(初始参数):要初始化的成员(初始值),...
{}
建议直接使用初始化列表来初始化所有的成员
---------------------------------------------------------------------------------------------------------------------------
#include<iostream>using namespace std;class Test{public:Test():a(0),b(0){}Test(int a,int b):a(a),b(b){}void show(){cout << "a = " << a << endl;cout << "b = " << b << endl;}private:int a;const int b;};int main(){Test t;t.show();Test t1(10,20);t1.show();return 0;}
2.拷贝/复制 构造函数
使用已经存在的对象拷贝或复制出一个新的对象
拷贝构造函数的参数:是本类类型的引用
使用:
构造函数(const 类名&){}
当没有显示定义拷贝构造函数时,编译器会自动生成
编译器默认的拷贝方式,称为浅拷贝
注意:
当成员变量有指针类型,然后在构造函数中进行了动态的内存分配,然后在析构函数中进行了动态内存的释放,那么必须写自己的拷贝构造函数。
拷贝构造函数的调用时机:
1.用已经存在的对象构造一个新对象
Test t2(t1);
Test t2 = t1;
2.当函数的参数是对象时
void func(Test t);
3.当函数返回的是一个对象时,有些编译器(g++)会做优化
例如:
Test func(){Test t(100,200);return t;// Test tmp = t;}int func(){int a = 10;return a;//int tmp = a;}int res = func();
---------------------------------------------------------------------------------------------------------------------------
练习:深拷贝与浅拷贝,要注意double free问题
#include<iostream>using namespace std;class Test{public:Test():a(0){b = new int(0);cout << "默认构造函数" << endl;}Test(int a,int b):a(a){this->b = new int(b);cout << "带参数的构造函数" << endl;}//带参数的构造函数private:Test(Test& other)//拷贝构造函数{cout << "拷贝构造函数" << endl;this->a = other.a;this->b = new int;*(this->b) = *(other.b);}public:~Test(){cout << "析构函数" << endl;delete b;}void show(){cout << "a = " << a << endl;cout << "b = " << *b << endl;}private:int a; int *b;};void func(Test& t)// Test& t = t1;{t.show();}Test func1(){Test t(100,200);return t;}int main(){Test t;t.show();Test t1(10,20);t1.show();cout << "---------1---------" << endl;//Test t2(t1);Test t2 = t1;//复制t2.show();cout << "----2-----" << endl;func(t1);cout << "--------3---------" << endl;Test t3;t3 = func1();t3.show();/*Test t3;t3 = t1;//复值t3.show();*/return 0;}
3.静态成员
为了实现一个类的多个对象之间的数据共享,C++提出静态成员的概念
静态成员变量
静态成员变量不属于某个具体的对象,属于某个类型
静态成员变量必须在类外初始化
类型 类名::静态成员变量名=初始值;
静态成员函数
专门用于处理静态成员变量
静态成员函数的调用方式:
类名::静态成员函数名();
注意:静态成员函数中没有this!!
--------------------------------------------------------------------------------------------------------------------------
#include<iostream>using namespace std;class Student{public:Student(){name = "Wuming";count++;}~Student(){count--;}void show(){cout << name << endl;}static int getCount()//静态成员函数{return count;}private:string name;static int count;};int Student::count = 0;//静态成员变量的初始化void func(){Student sa[100];cout << "count = " << Student::getCount() << endl;//?}int main(){cout << "count = " << Student::getCount() << endl;//?Student s;s.show();func();cout << "count = " << Student::getCount() << endl;//?//cout << "count = " << s.getCount() << endl;//?return 0;}
4.友元 friend
友元是对类的封装的一个补充,友元会赋予某些函数直接访问对象的私有成员的权限
友元函数:
普通的全局函数
friend 返回类型 函数名(参数列表);
类的成员函数
friend 返回类型 类名::成员函数名(参数列表);
友元类:
friend class 类名;
类的前置声明:
class 类名;
注:
友元关系是单向的
A是B的朋友,B不是A的朋友
友元关系是不可传递的
A是B的朋友,B是C的朋友,A不是C的朋友
------------------------------------------------友元函数----------------------------------------------------------------------------------------
#include<iostream>using namespace std;class Test{public:Test(){a = 100;}void show(){cout << "a = " << a << endl;}friend void func(Test);private:int a;};void func(Test t){cout << t.a << endl;}int main(){Test t;t.show();func(t);return 0;}
----------------------------------------------------友元类---------------------------------------------------------------------------
#include<iostream>using namespace std;class Girl;class Boy{public:void show(Girl);private:};class Girl{public:Girl(string name):name(name){}//friend void Boy::show(Girl);friend class Boy;private:string name;};void Boy::show(Girl g){cout << "this girl's name :'" << g.name << endl;}int main(){Girl girl("Hanmeimei");Boy boy;boy.show(girl);return 0;}
5.运算符重载
在C++中,所有的运算符都被处理成函数
运算符重载的本质就是函数重载
运算符对应函数名称,操作数对应函数参数,运算结果对应函数返回值
运算符函数:
返回类型 operator运算符(参数列表);
运算符重载函数:
友元函数
函数参数与操作数个数一致!
成员函数
函数参数要比操作数少一个!因为成员函数需要一个对象来调用
----------------------------------------重载运算符+,>,<<--------------------------------------------------------------------------------------
#include<iostream>using namespace std;class Complex{public:Complex(double real=0,double imag=0){this->real = real;this->imag = imag;}void show(){cout << "(" << real << "," << imag << "i)" << endl;}Complex operator+(Complex &c2){cout << "operator+++++++" << endl;Complex c3;c3.real = this->real + c2.real;c3.imag = this->imag + c2.imag;return c3;}//friend Complex operator+(Complex c1,Complex c2);friend bool operator>(Complex &c1,Complex &c2);friend ostream& operator<<(ostream &out,Complex &c);private:double real;double imag;};/*Complex operator+(Complex c1,Complex c2){cout << "operator+++++++" << endl;Complex c3;c3.real = c1.real + c2.real;c3.imag = c1.imag + c2.imag;return c3;}*/bool operator>(Complex &c1,Complex &c2){if(c1.real > c2.real){return true;}else{return false;}}ostream& operator<<(ostream &out,Complex &c){out << "(" << c.real << "," << c.imag << "i)";return out;}int main(){Complex c1(1,2);Complex c2(2,3);Complex c3 = c1 + c2;// c3 operator+(c1,c2) // c3 c1.operator+(c2)//c3.show();cout << c3 << endl; // cout operator<<(cout,c3)if( c1 > c2 )// bool operator>(c1,c2){cout << "c1 > c2" << endl;}else{cout << "c1 <= c2" << endl;}return 0;}
------------------------------------------------重载运算符++--------------------------------------------------------------------
#include<iostream>using namespace std;class Time{public:Time(int m=0,int s=0):m(m),s(s){}void show(){cout << m << ":" << s << endl;}friend Time& operator++(Time&);friend Time operator++(Time&,int);private:int m;int s;};Time& operator++(Time &t)//Time t = t1;{if(++t.s == 60){t.s = 0;++t.m;}return t;}Time operator++(Time &t,int){Time tmp = t;if(++t.s == 60){t.s = 0;++t.m;}return tmp;}int main(){Time t;t.show();Time t1(10,50);t1.show();Time t2 = ++t1;// t1 operator++(t1)t2.show();//10:51t1.show();//10:51Time t3 = t1++;// t1 operator++(t1)t3.show();//10:51t1.show();//10:52//t1.operator++(int)return 0;}
------------------------------------------------重载运算符=--------------------------------------------------------------------
#include<iostream>using namespace std;class Test{public:Test():a(0){b = new int(0);cout << "默认构造函数" << endl;}Test(int a,int b):a(a){this->b = new int(b);cout << "带参数的构造函数" << endl;}//带参数的构造函数Test(Test& other)//拷贝构造函数{cout << "拷贝构造函数" << endl;this->a = other.a;this->b = new int;*(this->b) = *(other.b);}public:~Test(){cout << "析构函数" << endl;delete b;}void show(){cout << "a = " << a << endl;cout << "b = " << *b << endl;}Test& operator=(Test &t)//赋值运算符重载函数{cout << "operator=" << endl;//1.防止自赋值if(this == &t){return *this;}//2.释放原有空间delete b;//3.分配新空间b = new int;//4.把值拿过来*b = *(t.b);//5.返回自引用return *this;}private:int a; int *b;};void func(Test& t)// Test& t = t1;{t.show();}Test func1(){Test t(100,200);return t;}int main(){Test t;t.show();Test t1(10,20);t1.show();cout << "---------1---------" << endl;Test t4;t = t4 = t1;//复值 t4 operator=(t1)t4.show();t.show();t4 = t4;return 0;}
--------------------------------------------------------------------------------------------------------------------
练习:求两点间的距离
#include <math.h>#include <stdio.h>using namespace std;class spot{ private:double x; double y; public:spot(double x,double y):x(x),y(y){}void show(){ cout<<"("<<x<<","<<y<<")"<<endl;}friend double print_distance1(spot &a,spot &b);//友元函数方法static double print_distance(spot a,spot b)//静态成员函数方法{double s;s = sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));return s;}}; double print_distance1(spot &a,spot &b){double s;s = sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));return s;}int main(){spot a(1,2);spot b(3,4);a.show();b.show(); double s,s1;s = spot::print_distance(a,b);printf("方法一:两点间距离为:%lf\n",s);s1 = print_distance1(a,b);printf("方法二:两点间距离为:%lf\n",s);return 0;}
阅读全文
0 0
- C语言常用知识点
- C语言常用知识点
- c语言常用知识点
- c++常用知识点3
- C程序中常用知识点注意事项
- C语言重要常用知识点梳理
- C语言知识点3
- C语言知识点-3
- C 知识点(3)
- 常用知识点
- 常用知识点
- C++【小结】3 - 小知识点
- C语言知识点总结3
- C 语言中一些非常用知识点 备忘录
- 高质量C编程10-常用知识点收集
- c知识点
- C 知识点
- C/C++知识点整理(3)
- 新朋实验室之玩具遥控车改装为ARDUINO蓝牙遥控小车(代码及制作过程开源)
- Monitorix-免费开源的单机Linux监控工具
- 装饰器模式(Decorator)和代理模式(Proxy)
- UVa 10213
- python 使用ConfigParser解析&修改配置文件
- c++常用知识点3
- Hadoop伪分布模式配置
- R桑基图
- android系统裁剪方法
- skynet源码分析(8)--skynet的网络
- VMWare启动centos 7时报内部错误
- ORACLE_参数笔记
- Laravel使用php artisan migrate报错: [PDOException] SQLSTATE[42S02]: Base table or view not found: 114
- Java的log4J完美日志篇