> 文档中心 > 第05节 C++特殊成员

第05节 C++特殊成员


const成员

const数据成员

  • const类型变量是不可以修改,只读模式
#include #include using namespace std;class MM{public:void  print(){//不能修改//num = 1001; 错误,只读模式cout << name << " " << num << endl;}protected:string name;const int num;//const 数据成员};int main(){return 0;}
  • 必须采用初始化参数列表方式进行初始化
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}void  print(){//不能修改//num = 1001; 错误,只读模式cout << name << " " << num << endl;}protected:string name;const int num;//const 数据成员};int main(){return 0;}

const成员函数

  • 写法上, const写在函数后面
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}void  print(){//不能修改//num = 1001; 错误,只读模式cout << name << " " << num << endl;}void print()const//const写在函数后面{}protected:string name;const int num;//const 数据成员};int main(){MM mm("对象", 18);mm.print();return 0;}
  • 常成员函数是不能够修改数据成员,只读数据成员
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}void  print(){//不能修改//num = 1001; 错误,只读模式cout << name << " " << num << endl;}void print()const//const写在函数后面{//name = "修改";错误,常成员函数不能修改数据//num = 199;cout << "常成员函数" << endl;}protected:string name;const int num;//const 数据成员};int main(){MM mm("对象", 18);mm.print();return 0;}
  • 常成员函数可以与普通函数同时存在

    • 普通函数和常成员函数相同时,普通对象优先调用普通函数
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}void  print(){//不能修改//num = 1001; 错误,只读模式cout << name << " " << num << endl;}void print()const//const写在函数后面{//name = "修改";错误,常成员函数不能修改数据//num = 199;cout << "常成员函数" << endl;}protected:string name;const int num;//const 数据成员};int main(){MM mm("对象", 18);mm.print();//普通对象优先调用普通函数return 0;}
+ 普通对象可以调用常成员函数
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}//void  print()//{////不能修改////num = 1001; 错误,只读模式//cout << name << " " << num << endl;//}void print()const//const写在函数后面{//name = "修改";错误,常成员函数不能修改数据//num = 199;cout << "常成员函数" << endl;}protected:string name;const int num;//const 数据成员};int main(){MM mm("对象", 18);mm.print();//当普通成员函数不存在时 普通对象可以调用常成员函数 打印“常成员函数”return 0;}

const对象: const修饰的对象

  • 常对象只能调用常成员函数
#include #include using namespace std;class MM{public:MM(string name, int num) :num(num){MM::name = name;//可以用,也可以不用初始化列表//MM::num = 1001;//必须要用初始化参数列表方式初始化}//void  print()//{////不能修改////num = 1001; 错误,只读模式//cout << name << " " << num << endl;//}void print()const//const写在函数后面{//name = "修改";错误,常成员函数不能修改数据//num = 199;cout << "常成员函数" << endl;}void printData(){cout << "普通函数" << endl;}protected:string name;const int num;//const 数据成员};int main(){MM mm("对象", 18);mm.print();//当普通成员函数不存在时 普通对象可以调用常成员函数 打印“常成员函数”const MM cmm("常对象", 20);//常对象调用常成员函数cmm.print();//cmm.printData();// 错误!常对象不能调用普通函数,只能调用常成员函数return 0;}

static成员

static成员是不属于对象,是属于类的,意味着是所有对象共有的,调用可以不需要对象,当然你可以用对象调用

static成员依旧受权限限定

#includeusing namespace std;class MM{public://MM(string name) :name(name),num(num){}//错误!不能采用初始化参数列表方式初始化MM(string name) :name(name){}protected:string name;static int num;};//类外初始化,不再需要static修饰,但是需要类名限定int MM::num = 1001;int main(){//cout << MM::num << endl;//不能访问!static成员依旧受权限限定return 0;}

static数据成员

  • 必须在类外初始化,不再需要static修饰,但是需要类名限定
#includeusing namespace std;class MM{public://MM(string name) :name(name),num(num){}//错误!不能采用初始化参数列表方式初始化MM(string name) :name(name){}protected:string name;static int num;};//类外初始化,不再需要static修饰,但是需要类名限定int MM::num = 1001;int main(){return 0;}
  • 类中初始化是错误的,不能采用初始化参数列表方式初始化
#includeusing namespace std;class MM{public://MM(string name) :name(name),num(num){}//错误!不能采用初始化参数列表方式初始化protected:string name;//static int num = 1;//错误的! 类中初始化是错误的};int main(){return 0;}
#includeusing namespace std;class MM{public://MM(string name) :name(name),num(num){}//错误!不能采用初始化参数列表方式初始化MM(string name ="") :name(name){num++;}protected:string name;public:static int num;};//类外初始化,不再需要static修饰,但是需要类名限定int MM::num = 1;int main(){//静态数据成员访问,可以不需要对象cout << MM::num << endl;//什么叫共有的MM mm("mm");//静态数据成员可以通过对象去访问cout << mm.num << endl;//此时num等于2MM array[3];//5MM* p = new MM("newMMM");//6cout << MM::num << endl;//6cout << p->num << endl;//6cout << mm.num << endl;//6delete p;p = nullptr;return 0;}

static成员函数

  • static写在函数前面即可

  • 调用非静态成员 必须要指定对象

#include#includeusing namespace std;class MM{public://MM(string name) :name(name),num(num){}//错误!不能采用初始化参数列表方式初始化MM(string name ="") :name(name){num++;}static void printMM();//static成员函数static void printData(MM& mm){cout << mm.name << " " << mm.num << endl;}protected:string name;public:static int num;};//类外初始化,不再需要static修饰,但是需要类名限定int MM::num = 1;//类外初始化,不再需要static修饰void MM::printMM(){//调用非静态成员 必须要指定对象//cout << name << endl;当这个函数不采用对象去调用,name没有来源//静态函数调用静态数据,没有什么要求cout << num << endl;cout << "静态成员函数" << endl;}int main(){//静态数据成员访问,可以不需要对象cout << MM::num << endl;//什么叫共有的MM mm("mm");//静态数据成员可以通过对象去访问cout << mm.num << endl;//此时num等于2MM array[3];//5MM* p = new MM("newMMM");//6cout << MM::num << endl;//6cout << p->num << endl;//6cout << mm.num << endl;//6delete p;p = nullptr;//静态成员函数调用,不需要指定对象MM::printMM();mm.printMM();MM::printData(mm);return 0;}

static对象

释放是最后释放的

友元

友元? friend描述的关系。友元只是提供一个场所,赋予对象具有打破类的权限定(无视权限)

#include #include using namespace std;class MM{public:MM(string name, int age) :name(name), age(age){}void print(){cout << name << "\t" << age << endl;}friend void printData(){//不属于类,不能直接访问成员// cout << name << "\t" << age << endl;MM mm("好朋友", 29);//友元函数提供一个场所,让对象无视权限cout << mm.name << mm.age << endl;}protected:string name;private:int age;friend void printData2();};//不需要friend修饰,不需要类名限定void printData2(){}int main(){MM mm("夏丽",18);mm.print();return 0;}
#include #include using namespace std;void printData();//声明语法class MM{public:MM(string name, int age) :name(name), age(age){}void print(){cout << name << "\t" << age << endl;}friend void printData(){//不属于类,不能直接访问成员// cout << name << "\t" << age << endl;MM mm("好朋友", 29);//友元函数提供一个场所,让对象无视权限cout << mm.name << mm.age << endl;}protected:string name;private:int age;friend void printData2(MM& mm);};//不需要friend修饰,不需要类名限定void printData2(MM& mm){cout << mm.name << "\t" << mm.age << endl;}//void printData()//{////不属于类,不能直接访问成员//// cout << name << "\t" << age << endl;//MM mm("好朋友", 29);////友元函数提供一个场所,让对象无视权限//cout << mm.name << mm.age << endl;//}int main(){MM mm("夏丽",18);mm.print();printData2(mm);printData();return 0;}

友元函数

  • 普通友元函数

  • 以另一个类的成员函数充当友元函数,顺序如下:

    • B 类
    • A类
    • A类的友元函数(B类的成员函数)
#include #include using namespace std;void printData();//声明语法class MM{public:MM(string name, int age) :name(name), age(age) {}void print(){cout << name << "\t" << age << endl;}friend void printData(){//不属于类,不能直接访问成员//cout << name << "\t" << age << endl;MM mm("好朋友", 29);//友元函数提供一个场所,让对象无视权限cout << mm.name << mm.age << endl;}protected:string name;private:int age;friend void printData2(MM& mm);};//不需friend修饰,不需要类名限定void printData2(MM& mm){cout << mm.name << "\t" << mm.age << endl;}//void printData() //{////不属于类,不能直接访问成员////cout << name << "\t" << age << endl;//MM mm("好朋友", 29);////友元函数提供一个场所,让对象无视权限//cout << mm.name << mm.age << endl;//}//前向声明class B{public:void printA();void printData();protected:};class A{public:friend void B::printA();protected:string name = "A";};//成员函数实现,一定是在另一个类的下面实现void B::printA(){A a;cout << a.name << endl;}void B::printData(){A a;//错误 ,不是他的A类的友元函数,所以不能访问保护和私有属性//cout << a.name << endl;}int main(){MM mm("美女", 18);mm.print();printData2(mm);printData();B b;b.printA();return 0;}

友元类

#include #include using namespace std;class MM{friend class GG;public:MM(string name, int age) :name(name), age(age) {}protected:string name;int age;};class GG{public:void print(){MM mm("mm", 18);cout << mm.name << "\t" << mm.age << endl;}void printMM(MM& mm){cout << mm.name << "\t" << mm.age << endl;}MM& returnMM(MM& mm){return mm;}protected:};//互为友元类的写法class A{friend class B;public:void printData();protected:string data = "A";};class B{public:friend class A;void printData(){A a;cout << a.data << endl;}protected:string data = "B";};void A::printData(){B b;cout << b.data << endl;}int main(){MM mm("mm", 18);GG gg;gg.print();gg.printMM(mm);//cout << gg.returnMM(mm).name << endl;  错误,出了友元类,没有权限//互为友元B b;b.printData();A a;a.printData();return 0;}

this指针与explicit

explicit修饰构造函数使用,不让隐式转换构造

this指针

  • 避免形参名和数据成员同名,通指对象的地址

  • 充当函数返回值,返回对象自身,用*this表示对象本身

  • 静态成员函数中是不能使用this指针

上节课作业