const修饰

本文详细介绍了C++中const修饰成员变量、指针变量、函数参数和成员函数的用法。讲解了const如何影响指针和指针所指数据的可变性,以及在const成员函数中如何使用mutable关键字。同时,探讨了const函数调用非const函数的可能性及const_cast的使用场景。
摘要由CSDN通过智能技术生成

1.const 修饰成员变量

int main()
{
    int a1=3;   
    const int a2=a1;    // a2 不可以修改

    int * a3 = &a1;   
    const int * a4 = &a1;   // (*a4)++ 不可以,a4++ 可以
    int * const a5 = &a1;   // (*a5)++ 不可以,a5++ 可以 
                            // a5和上面的a4表示一样
    int const * const a6 = &a1;   ///(*a6)++,a6++ 都不可以
    const int * const a7 = &a1;   ///(*a7)++,a7++ 都不可以

    return 0;
}

const修饰指针变量时:

  只有一个const时

  如果const 位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,指针可以修改,即可以指向其他的内存单元。如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;但是指针所指的数据可以通过解引用修改。

  两个const

  即 “ * ” 左右各一个,则表示指针和指针所指数据都不能修改。

2.const修饰函数参数

  表示传递过来的参数在函数内不可以改变,与上面修饰变量时的性质相同。

eg:

void func(const int len) 
{
     len = 5;   // 编译出错
}

程序中当我们调用这个函数时,编译会出错。
    在类中声明变量为const类型,但是不可以初始化

    const常量的初始化不可以在构造函数函数体内初始化,必须在构造函数初始化列表中初始化。

eg:

#include <iostream>
using namespace std;

class A
{
    public:
        A(int _a) : a(_a) {};
        /*
        A(int _a) // 编译发生错误
        {
            a = _a;
        }
        */
        void show()
        {
            cout << "_a = " << a << endl;
        }
    private:
        const int a;
};

int main()
{
    A a(100);
    a.show();
}

 为了让一个属于具体的一个对象的const变量,我们使用枚举让其值在整个类中都恒定不变。

eg:

class A
{
    private:
        enum {_a = 100};
    public:
        int array[_a];
};

    枚举常量不会占据对象的存储空间,在编译时被全部求值. 
但是,它隐含的数据对象类型为整形,不能表示其他类型。

必须在构造函数的初始化列表中有以下几种情况:

  • 类的const常量
  • 类的引用类型成员
  • 没有默认构造函数的类的类型成员
  • 如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数

3.const成员函数

  任何不修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或调用了其他非const成员函数,编译器就会指出错误。

eg:

class A
{
    public:
        void Ap1();
        int Ap2();
        int getcount() const;
    private:
        int num;
};

int A::getcount() const
{
    num++;     // 编译出错,企图修改数据成员
    Ap2();    // 编译出错,企图调用非const函数

    return num;
}

  在同一个类中,是否可以仅通过const定义两个函数名字、参数、返回值完全相同的两个成员函数,用下面的实例来说明:

eg:
#include <iostream>
using namespace std;

class A
{
    public:
        A(int n) : num(n){}
        void Ap()
        {
            cout << "not_count Ap()" << " : " << num << endl;
        }
        void Ap() const
        {
            cout << "count Ap()" << " : " << num << endl;
        }
    private:
        int num;
};

int main()
{
    A a(10);
    a.Ap();

    A const a1(25);
    a1.Ap();

    return 0;
}

结果:
not_count Ap() : 10
count Ap() : 25

从上述程序和结果可以看出:
    同函数名、参数、返回值可以仅通过是否为const来定义为类的两个成员函数。在调用时,const对象调用const成员函数,非const对象调用非const成员函数。

  虽然不可以在const函数改变成员变量的值,但是如果在const函数中改变成员变量的值,则可以使用mutable这个关键字。

mutable关键字

  mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量(mutable只能由于修饰类的非静态数据成员),将永远处于可变的状态,即使在一个const函数中。

假如类的成员函数不会改变对象的状态,那么这个成员函数一般会声明为const。但是,有时我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该用mutalbe来修饰。

  看下面的例子:

eg:

#include <iostream>
using namespace std;

class A
{
    public:
        A(int n) : num(n){}
        void Ap() const
        {
            num++;
            cout << num << endl;
        }
    private:
        mutable int num;
};

int main()
{
    A const a(10);
    a.Ap();

    A const a1(25);
    a1.Ap();

    return 0;
}

结果:
11
26

    从上述程序与结果,可知const修饰的函数中的成员变量已经改变,并且非const对象可以调用const函数。

  但是,还有非const函数时,非const对象不可以调研那个const函数(否则,类的数据变量就会发生变化)。

问题:

  当类中存在只有 是否为const 不同的两个函数时,const函数是否可以暂时调用那个非const函数?

  是可以的。我们可以用const_cast将转化掉表达式的const性质

#include <iostream>

using namespace std;

class A
{
    public:
        A(int a) : _a(a){}
        void print()
        {
            cout << "not_const print : " << _a << endl;
        }
        void print() const
        {
            cout << "const print : " << _a << endl;
        }
    private:
        int _a;
};
int main()
{
    A a(10);
    a.print();
 //   const_cast<A> a.print(); // 编译报错,单纯用类不行,

    const A *b1 = new A(20);
    const_cast<A *> (b1)->print();
    b1->print();

    return 0;
}


结果:
not_const print :10
const print : 20
not_const print :20

const_cast用法:

class B{ public: void print();};

const B b;

const B *c;

  1.  B b1 = const_cast<B&>(b);
  2. B *b2 = const_cast<B*>(&b);
  3. B &b3 = const_cast<B&>(b);

返回类型是const

  const返回类型只有在修饰指针或引用是才有用。单凭const返回类型不可以重载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值