this指针
this 指针,作用是指向成员函数所作用的对象
非静态成员函数中可以直接使用this代表指向该函数作用的对象的指针
静态成员函数中不能使用this指针,因为静态成员函数并不作用于某一个具体的对象
静态成员函数真实的参数个数与写出的个数一样,普通函数多一个,就是this指针
#include <iostream>
using namespace std;
class A{
int i;
public:
void pri(){
cout<<"hello"<<endl;
}
};
int main()
{
A a;
a.pri();
return 0;
}
这个例子会输出”hello”,说明调用了pri函数,但是没有对a初始化,因为this指针相当于调用了
void pri(A *this){cout<<"hello"<<endl;}
这样一句话。。。。但是如果输出i的值,会出错
静态成员
在说明前面加了static加了关键字的成员
sizeof不会计算静态成员变量
静态成员遍历,为所有的对象共享
静态成员函数并不具体作用于某个对象
静态成员不需要对象就能访问
静态成员变量(函数)是全局变量(函数),那怕一个对象都不存在,它也存在
为什么引入?因为把和某些类相关的变量和函数写进类,便于维护
静态成员函数中,不能访问非静态成员变量和函数。
#include <iostream>
using namespace std;
class CRectangle
{
private:
int w, h;
static int nTotalArea;//静态成员变量
static int nTotalNumber;
public:
CRectangle(int w_, int h_){
//构造函数
w=w_;
h=h_;
nTotalNumber++;
nTotalArea+=w*h;
};
~CRectangle(){
//析够函数
nTotalArea-=w*h;
nTotalNumber--;
cout<<endl<<"destruct "<<w<<" "<<h<<endl;
};
CRectangle(const CRectangle &c){
//复制构造函数
h = c.h+1;
w = c.w+1;
nTotalNumber++;
nTotalArea += h*w;
}
void pri(){
cout<<endl<<"w is:"<<w<<" h is:"<<h<<endl;
}
static void PrintTotal(){
cout<<endl<<nTotalNumber<<" "<<nTotalArea;
};
};
//注意,静态成员变量要在类外边进行声明,要不然会报错
int CRectangle::nTotalNumber=0;
int CRectangle::nTotalArea=0;
int main()
{
CRectangle r1(2,2), r2(3,3);
CRectangle r3(r2);
CRectangle::PrintTotal();//输出
r1.PrintTotal();//输出
r3.pri();
return 0;
}
结果(注意析够函数):
3 29
3 29
w is:4 h is:4
destruct 4 4
destruct 3 3
destruct 2 2
成员对象和封闭类
有成员对象的类叫做封闭类
先执行成员函数的构造函数,在执行封闭类的构造函数
成员对象的构造函数调用次序和对象成员在类中的说明次序一致,与初始化列表无关
封闭类消亡的时候,先指向封闭类的析够函数,在执行成员对象的析够函数。次序和构造函数的调用相反(构造和析够相反的)。
#include <iostream>
using namespace std;
class CTyre
{
private:
int radius;
int width;
public:
CTyre(int r, int w):radius(r), width(w){
cout<<endl<<"in CTyre constructor"<<endl;
}
void pri(){
cout<<"in ctyre:"<<radius<<" "<<width<<endl;
};
~CTyre(){
cout<<endl<<"in ctyre destructor"<<endl;
}
};
class CEngine
{
public:
CEngine(){
cout<<endl<<"in CEngine constructor"<<endl;
}
~CEngine(){
cout<<endl<<"in CEnigne destructor"<<endl;
}
};
class CCar{
//封闭类
private:
int price;
CTyre tyre;//成员对象
CEngine engine;
public:
CCar(int p, int tr, int tw):price(p), tyre(tr, tw){
cout<<endl<<"in CCar constructor"<<endl;
}//初始化列表
void print(){
tyre.pri();
}
~CCar(){
cout<<endl<<"in CCar destructor"<<endl;
}
};
int main()
{
CCar car(1,2,3);
car.print();
return 0;
}
结果:
in CTyre constructor
in CEngine constructor
in CCar constructor
in ctyre:2 3
in CCar destructor
in CEnigne destructor
in ctyre destructor
封闭类和复制构造函数
#include <iostream>
using namespace std;
class A{
public:
A(){
cout<<"default"<<endl;
}
A(const A&a){
cout<<"in A copy"<<endl;
}
};
class B{
A a;
public:
B(){
cout<<"in B copy"<<endl;
}
};
int main()
{
B b1, b2(b1);
return 0;
}
default
in B copy
in A copy
常量对象、常量成员函数和常引用
如果不希望某个对象的值被改变,则定义该对象的时候,可以在前面加上const关键字
常量成员函数执行奇迹不应修改其作用的对象,因此,常量成员函数中不能修改成员变量的值(静态成员变量除外),也不能调用同类的非常量成员函数(静态成员函数除外)。
#include <iostream>
using namespace std;
class Sample
{
private:
static int v;
public:
int value;
void GetValue() const;
void func(){}
Sample(){}
void print(){
cout<<v<<endl;
}
};
void Sample::GetValue() const {
//value=0//error
v++;
}
int Sample::v=0;
int main()
{
Sample s;
s.GetValue();
s.print();
return 0;
}
结果是:1
说明,常量成员函数可以修改静态成员遍历
友元
友元分为友元函数和友元类
一个类的友元函数(有可能是全局函数)可以访问这个类的私有成员
如果A是B的友元类,那么A的成员函数可以访问B的私有成员。
友元类之间的关系不能传递,不能继承。
#include <iostream>
using namespace std;
class CCar;
class CDriver{
public:
void ModifyCar(CCar *pCar);
};
class CCar{
private:
int price;
friend int MostExpensiveCar(CCar cars[], int total);
friend void CDriver::ModifyCar(CCar *pCar);
public:
void set_price(int p){
price=p;
}
};
void CDriver::ModifyCar(CCar *pCar) {
pCar->price+=1000;//注意,这里访问了CCar类的私有成员
}
int MostExpensiveCar(CCar cars[], int total){
int tmpMax=-1;
for (int i = 0; i < total; ++i) {
if(cars[i].price>tmpMax) tmpMax=cars[i].price;
}
return tmpMax;
}
int main()
{
CCar c1, c2;
c1.set_price(12);
c2.set_price(13);
CCar cars[2]={c1, c2};
cout<<MostExpensiveCar(cars, 2);
return 0;
}
结果
13