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;}



原创粉丝点击