友元函数
友元函数分为友元全局函数和友元成员函数。
下面是一个友元全局函数的例子:
class Coordinate
{
friend void printXY(Coordinate &c);
public:
Coordinate(int x, int y);
private:
int m_iX;
int m_iY;
};
友元函数的应用
void printXY(Coordinate &c)
{
cout << c.m_iX << c.m_iY << endl;//友元函数可以顺利访问private
}
int main()
{
Coordinate coor(3, 5);
printXY(coor);//传入对象名而非地址
return 0;
}
下面是友元成员函数的例子
class Coordinate
{
friend void Circle::printXY(Coordinate &c);//是Circle类的成员函数
public:
Coordinate(int x, int y);
private:
int m_iX;
int m_iY;
};
class Circle
{
void printXY(Coordinate &c)
{
cout << c.m_iX << c.m_iY << endl;
}
};
int main()
{
Coordinate coor(3, 5);
Circle circle;
circle.printXY(coor);//传入对象名而非地址
return 0;
}
友元函数也存在一定的风险,在上述代码中,通过成员函数很方便的访问Coordinate的私有成员,很方便,但同时也破坏了它的封装性,当不小心改了这个值以后,也很不容易察觉。
友元类
友元类的声明和友元函数的声明很相似,如下述代码
class Circle;//要告诉计算机,这个类是定义过的
class Coordinate
{
friend Circle;
public:
Coordinate(int x, int y);
private:
int m_iX;
int m_iY;
};
在实现Circle类的时候,可以在类中数据成员中包含一个友元的类,并调用其私有成员,如下述代码所示
class Circle
{
public:
void printXY(c)
{
cout << c.m_iX << c.m_iY << endl;
}
private:
Coordinate m_coor;
};
接下来我们来讲一下友元的注意事项
1.友元关系不可传递
2.友元关系的单向性
3.友元声明的形式和数量不受限制
最后我们需要知道的是友元只是封装的补充,其本身并不是一个很好的语法。友元破坏了类的封装性,所以尽量不要用友元。
静态 (static)
C++中的静态分为静态数据成员和静态成员函数。
静态数据成员依赖于类,而不依赖于对象,这意思就是说静态数据成员即使不实例化,在内存中也存在,他不需要在构造函数中实例化,它的实例化往往是单独进行的,而普通的数据成员不实例化就不存在,如下述代码:
class Tank
{
public:
Tank(){ s_iCount++; }//产生新坦克,则坦克数增多
~Tank(){ s_iCount--; }
static int getCount(){ return s_iCount; }//静态成员函数
static int s_iCount; //静态数据成员,记录了我方坦克的数量
private:
string m_strCode;
};
int Tank::s_iCount = 0;//不需要再加关键字static
那么作为访问方法来说有两种,一种是不通过类,而是直接通过对象的访问方法;另一种是如果我们定义了对象,可以通过对象的方式来调用。如下代码所示
int main()
{
cout << Tank::getCount() << endl;//直接访问
cout << Tank::s_iCount << endl;
Tank tank;
cout << tank.getCount() << endl;//通过对象访问
cout << tank.s_iCount << endl;
return 0;
}
静态函数不能调用非静态的成员,因为static成员一直存在,但是如果没有实例化的话,就无法调用非静态的成员。
静态函数不能加const,因为const修饰的是this指针,静态函数本身没有this指针,所以不可能使用。
下面来说一下静态的注意事项:
1.静态数据成员必须进行单独的初始化
2.静态的成员函数不能调用非静态的成员函数和非静态的数据成员,反之可以。
3.静态的数据成员只有一份,且不依赖于对象而存在。