有时,让某些特定的非成员函数访问类内成员能高效率的完成工作,友元就是这样一种机制,可以将类A整体或其中的某函数声明为类B的友元,当然非类成员函数更是可以,它们被声明为友元后,可以访问类B的所有成员。
友元通常只在类内声明。
class A{
public:
.....
private:
.....
};
class B{
friend class A;
public:
.....
private:
.....
};
|
所有友元的声明最好放到一起,在类的最前或最后面。
函数形式
class A{
public:
void func(class B&);
private:
//.....
};
class B{
friend void A::func(B&);
public:
//.....
private:
//.....
};
|
友元函数最好拥有一个目标友元类的参数,方便其访问目标友元类的成员。
函数形式时要求类A在类B之前定义。
当友元函数有重载形式时,一定要分清哪些要作为其它类的友元,哪些不能。
静态成员
有时需要某类的所有对象均能访问一个数据成员,比如说该类对象个数的计数器。前面所定的所有成员在创建对象后只属于这个对象,对象之间是不能直接访问彼此的非公有成员的。静态成员可派上用场,其不属于任何对象,只是属于这个类的。在其前面加关键字 static 将其声明为静态成员。
class A{
public:
static int account;
static int increase();
static int decrease();
private:
//.....
};
|
访问形式为 A::account;A::increase();
静态成员具有类成员的通常性质,将其声明为私有则类外不可访问。
类的静态成员函数是没有this指针的,决定了它不能直接访问非静态成员,也不能声明为虚函数。
使用静态成员的好处。
1.静态成员在类的作用域内,避免了直接被其它代码修改(当然前提是声明其为私有)。
2.保持了良好的数据封装,程序的可读性也大大增强。
在类外使用静态成员或实现静态成员函数时,其前面不用加static关键字,只出现于类内定义时。
因为其没有this指针,其也就不能被声明为常成员函数。其也不能被声明为虚函数。
静态数据成员的声明与定义(decleration and defination)
上面的代码只是声明类A具有一个静态成员,我们在使用它前必须定义它并初始化,否则出错。
int main(){
cout<<" account is "<<A::account<<endl;
}
|
出现连接错误 MinGW/include/c++/3.2.3/ostream:119: undefined reference to `A::account'
int A::account=4;
int main(){
cout<<" account is "<<A::account<<endl;
}
|
这样既可。
注意:类的静态数据成员不能依靠构造函数初始化,只能手动定义并初始化一次(在所写该语句处),所以将其定义和初始化写在含有类的非内联成员函数的文件内最好。
因为是静态成员,所以放在全局域定义并初始化,直接在main函数中会被认为是重复定义。
int main(){
int A::account=4;
cout<<" account is "<<A::account<<endl;
}
|
编译报错:redeclaration of `int A::account'
特例:静态常量(static const),其可以在类内声明处初始化
class A{
public:
static const int account2=20;
static int increase();
static int decrease();
private:
//.....
};
|
但使用其前仍需要定义
静态成员因为不属于任何对象,只属于该类,所以有一些特殊的性质,我们可以在类A内定义一个类A自己的静态对象
class A{
public:
static A obj1;
private:
//.....
};
|
不可定义非静态成员的类A的对象,只可是指针或者引用。
静态常量可以作为函数的默认参数
class A{
public:
static const int account=3;
void asg(int refi=account){
i=refi;
}
int i;
private:
//.....
};
int main(){
A obj1;
obj1.asg();
cout<<" i is "<<obj1.i<<endl;
}
|
结果为 i is 3
非静态常量因为是属于对象的,能否访问是问题一,而且其值也不一定相同,一般不用于默认参数。
阅读(785) | 评论(0) | 转发(0) |