Chinaunix首页 | 论坛 | 博客
  • 博客访问: 299106
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: C/C++

2008-10-02 20:24:52

有时,让某些特定的非成员函数访问类内成员能高效率的完成工作,友元就是这样一种机制,可以将类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:
    //.....

};

但使用其前仍需要定义

const int account2;


静态成员因为不属于任何对象,只属于该类,所以有一些特殊的性质,我们可以在类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) |
给主人留下些什么吧!~~