c++类和对象(二)

1.this指针

  • 指向成员函数所作用的对象
  • 非静态成员函数中,可以直接使用this来代表指向该函数作用的对象的指针
  • 静态成员函数中,不能使用this指针,因为静态成员函数并不具体作用于某个对象

2.静态成员变量与静态成员函数

  • 在定义前面加上static关键字的成员
  • 静态成员变量为所有对象共享
  • sizeo运算符不会计算静态成员变量
  • 普通成员函数必须具体作用某个对象,静态成员函数并不具体作用于某个对象
  • 静态成员不需要通过对象就能访问
  • 静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也是存在的
  • 静态成员函数的本质上是全局函数
  • 设置静态成员这种机制的目的是将和某些类紧密联系的全局变量和函数写到类里面,看上去像一个整体,便于维护和理解

如何访问静态成员

  • 类名::成员名
  • 对象名.成员名
  • 指针->成员名
  • 引用.成员名

注意:

  • 必须在定义类的文件中,对静态成员变量进行一次说明或者初始化,否则编译能通过,链接不能通过
  • 在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数

3.成员对象和封闭类

  • 有成员对象的类,叫封闭类(enclosing)
  • 任何生成封闭类对象的语句,都要让编译器知道如何初始化,一般做法是通过封闭类的构造函数初始化列表
  • 封闭类对象生成时,先执行所有对象成员的构造函数,然后才执行封闭类的构造函数
  • 对象成员的构造函数调用次序和对象成员在类中的说明次序,与它们在成员初始化列表中出现的次序无关
  • 当封闭类的对象消亡时,先执行封闭类的析构函数,然后再执行成员对象的析构函数,次序和构造函数的调用次序相反

4.常量对象
如果不希望某个对象的值被改变,则定义该对象的时候,前面可以加const关键字

class Sample {
    private :
        int value;
    public:
        Sample() { }
        void SetValue() { }
};
const Sample Obj;   // 常量对象
Obj.SetValue ();    //错误 。常量对象只能使用构造函数、析构函数和 有const 说明的函数(常量方法)

5.常量成员函数

  • 在类的成员函数说明后面可以加上const关键字,则该成员函数称为常量成员函数
  • 常量成员函数执行期间,不应该修改其对象,因此,不能修改成员变量的值(静态类型除外),也不能调用同类的非常量成员函数(静态类型除外)
  • 在定义常量成员函数和声明常量成员函数时都应该使用const关键字
  • 如果一个成员函数没有调用非常量成员函数,也没有修改成员函数变量的值,那么最好将其定义为常量成员函数
  • 两个成员函数,名字和参数表都一样,一个是const,另一个不是,它们是重载关系
class Sample {
    private :
        int value;
    public:
        void func() { };            //非常量成员函数
        Sample() { }                //构造函数
        void PrintValue() const;    //常量成员函数
        void SetValue() const;      //常量成员函数
};
void Sample::PrintValue() const { //此处不使用const会导致编译出错
    cout << value;
}
void Sample::SetValue() const { //此处不使用const会导致编译出错
    value = 0;      //wrong
    func();         //wrong
}
void Print(const Sample & o) {
    o.PrintValue(); //若 PrintValue非const则编译错
}
const Sample Obj;
Obj.PrintValue (); //常量对象上可以使用常量成员函数

6.常引用
引用前面可以加const关键字,作为常引用,不能通过常引用,修改其引用的常量

7.mutable成员变量
用mutable声明的成员变量,可以在const成员函数中修改它的值

8.友元
友元分为友元函数和友元类

  • 友元函数:一个类的友元函数可与访问该类的私有成员
    可以将一个类的成员函数(包括构造函数、析构函数)声明为另一个类的友元函数
class CCar ; //提前声明 CCar类,以便后面的CDriver类使用
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); //声明友元
};
void CDriver::ModifyCar( CCar * pCar)
{
    pCar->price += 1000; //汽车改装后价值增加
}
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()
{
    return 0;
}
  • 友元类:如果A是B的友元类,那么A的成员函数可与访问B的私有成员
    友元类之间的关系不能传递,不能继承
class CCar
{
    private:
        int price;
    friend class CDriver; //声明CDriver为友元类
};
class CDriver
{
    public:
        CCar myCar;
        void ModifyCar() {//改装汽车
            myCar.price += 1000;//因CDriver是CCar的友元类,
            //故此处可以访问其私有成员
        }
};
int main(){ return 0; }

猜你喜欢

转载自blog.csdn.net/whitefish520/article/details/100840440
今日推荐