c++常对象和常成员函数详解

常对象

常对象是指该对象在其生命周期内,其所有的数据成员的值都不能被改变;定义对象时加上关键字const,该对象就是常对象,其一般形式如下:

类名 const 对象名[(实参类别)];
或者
const 类名 对象名[(实参类别)];

形如:const CComplex num;

需要特别说明的是:

1. 常对象只能调用常成员函数,不能调用普通成员函数
(除了隐式调用析构函数和构造函数),常成员函数是常对象的唯一对外接口;
2. 现在编译系统只检查函数的声明,只要发现调用了常对象的成员函数,而且该函数未被声明为const,编译阶段就报错
3. 常对象在被定义时需要被初始化;

类设计源码:

class CComplex
{
public:
    //普通构造函数
    CComplex(int nReal, int nImag):m_nReal(nReal),m_nImag(nImag)
    {
        cout << "common constructor function" << endl;
    }
    int GetRealNum()
    {
        return m_nReal;
    }
private:
    int m_nReal;
    int m_nImag;
};
//常对象
const CComplex num1(1,1);
//error:不能将“this”指针从“const CComplex”转换为“CComplex &”
int nReal = num1.GetRealNum();

编译错误的原因是,目前该函数还是普通函数,它可能会修改成员变量;为了常对象能调用GetRealNum函数,应该将该函数设计成常成员函数;

形如int GetRealNum() const;

常数据成员

如果我们希望在创建对象后,该对象的某个数据成员就保持不变,我们可以将这个数据成员设置为常数据成员;常数据成员只能通过构造函数初始化列表进行初始化,其他形式的函数均不能进行数据的赋值;

常成员函数

若将成员函数设置为常成员函数,则只能引用本类中的数据成员,而不能修改它;常成员函数可以引用const数据成员,也可以引用非const的数据成员;常成员函数的一般形式为:

类型名 函数名(形参列表) const

这里的const关键字是函数类型的一部分,在函数声明和函数定义时都要带const关键字,否则被编译器认为是不同的两个函数,但是在函数调用的时候不必带const;

形如:

//声明和定义一起实现
int GetRealNum() const
{
   return m_nReal;
}

函数API设计总结

(1) 若我们定义了一个常对象,则指向这个常对象的指针变量或者对象引用也需要是const类型的;一般形式如下:

const 类型名* 指针变量名;
const 类型名& 引用名;

(2)常对象的唯一对外接口是常成员函数;
(3)为了节约时间开销和时间开销,一般将函数形参定义为指针或者引用类型;
(4)若不希望传入的实参对象被修改,应该将形参定义指向常对象的指针变量或者引用;

根据以上几点知识,我们进行类设计时,最好遵循以下两点结论:

1.将不涉及数据成员修改的函数定义为常成员函数

形如: int GetRealNum() const

2.当发生函数调用时,希望传入的实参对象不被修改,应当将形参定义为const类型的指针或者引用;这个实参可以是const类型的,也可以是非const类型的,函数接口兼容性更加,形如:

static void TransByPointer(const CComplex* obj)
{
    cout << "TransByPointer 
" << endl;
}

static void TransByRefence(const CComplex& obj)
{
    cout << "TransByRefence 
" << endl;
}

下面给出const相关知识的具体调用说明:

数据成员 非const的普通成员函数 const成员函数
非const的普通数据成员 可以引用,也可以改变值 可以引用,但不可以改变值
const数据成员 可以引用,但不可以改变值 可以引用,但不可以改变值
const对象 不允许 可以引用,但不可以改变值
原文地址:https://www.cnblogs.com/jinxiang1224/p/8468238.html