const修饰函数参数,返回值,成员函数

一提到到const 关键字,我们首先想到的可能是const常量。
但const的功能可不仅仅局限于此,它可以修饰函数参数,返回值,甚至函数的定义体。
const是constant的缩写,“恒定不变”的意思。
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

下面我们讲一下以下三种情况:
1.const修饰函数的参数
2.const修饰函数的返回值
3.const修饰成员函数

1.const修饰函数的参数
 防止传入的参数代表的内容在函数体内被改变,注意仅仅对指针和引用有意义。
        如果是 按值传递,传给参数的仅仅是实参的副本,即使在函数体内改变了形参,实参也不会得到影响。

1.1 参数按“值传递”
代码块:
int func(const int x)
{ 
 //x += 10;//报错,表达式必须是可修改的左值
 return x;
}
分析:输入的参数采用“值传递”,函数将自动缠身临时变量用于复制该参数,将在函数调用结束后自动销毁,所以无需保护。

1.2 参数按“指针传递”
代码块:
char* Strcpy(char*dst, const char* src)//src用const修饰可以防止意外地改变指针
{
 strcpy(dst, src);//把src复制拷贝给dst
 //strcpy(src, dst);//系统报错
 return src;
}

分析:参数按指针传递,函数将对const修饰的指针进行保护,防止被修改

1.3 非内部数据类型的参数
对于非内部数据类型,如果采用“按值传递”,在函数体内,将会产生这个类型的临时对象用作实参的拷贝。
临时对象的产生,必然会调用临时对象的构造函数和析构函数,效率将会大大下降。
那么该如何去提高它的效率呢?
最有效的方法就是采用 “引用传递”
引用其实就是实参的别名,它和实参的内存地址相同,引用的改变将会引起外部实参的改变。
代码块:
class base
{
public:base(int x = 1)
    :b(x)
    {}
    void operator= (const base& BB)//这里的BB是B的引用,加了const保护
    {
     b = BB.b;//赋值操作
    }
 int b;
};
int main()
{
 base B(42);
 base B1;
 B1.operator= (B);
 cout <<"b="<<B1.b << endl;
 system("pause");
 return 0;
}

分析:“引用传递”不需要产生临时对象,所以也就不存在构造析构函数的问题,但是有可能会改变外部的实参,所以在operator=函数中参数前面加了const保护,防止外部实参被有意无意的改变。



2.const修饰函数的返回值
2.1 如果函数的返回值是一个指针的话,加上const修饰。
即表示该指针指向的内容不能被改变,且只能用const修饰的同类型指针变量接收。
代码块:
const char* Strcpy(char*dst, const char* src)
{
 strcpy(dst, src);
 return dst;
}
int main()
{
 char* msg = "abcdefg";
 char msg1[20];
 const char* msg2 = Strcpy(msg1, msg);//msg2不用const修饰的话,将会报错。
 system("pause");
 return 0;
}


2.2 如果函数的返回值是“引用”的话,加上const修饰。
这种方式一般出现在类的赋值运算函数中。比如实现日期类的operator+=()函数。

3.const修饰成员函数
我们都知道每个类的成员函数参数都有一个隐含的this指针,若在成员函数后面加const
则表明const修饰的是this指针所指向的对象,也就是保证调用这个const成员函数的对象的数据成员在函数内不会被改变。
若不慎修改,编译器将会报错。
提高了程序的健壮性。
class base
{
public:base(int x = 1)
    :b(x)
  {}
    void func (void)const//const成员函数  这里相当于const base *this
    {
     //b++;//表达式必须是可修改的左值  
     cout << "func()::b="<<this->b << endl;
    }
    void dis()//普通成员函数 
    {
     b++;
     cout <<"dis()::b=" << this->b << endl;
    }
 int b;
};

int main()
{
 base B(42);//非const对象
 const base B1(24);//const类型对象
 B.func();//非const对象调用const成员函数
 B.dis();//非const对象调用普通成员函数 
 B1.func();// const对象调用const成员函数
 //B1.dis();//报错,对象包含与成员函数的类型限定符不兼容
 system("pause");
 return 0;
}

结论:
1. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。
2. const对象的成员是不可修改的。
3.const成员函数不可以修改对象的数据。

猜你喜欢

转载自blog.csdn.net/komacc/article/details/80384193
今日推荐