C++总的const使用说明

C++总的const使用说明

1. const修饰类成员变量

  程序:

#include <iostream>
using namespace std;

class A
{
    public:
        A(int size) : SIZE(size) {};
    private:
        const int SIZE;
};

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

  说明:
  (1)    在类中声明变量为const类型,但是不可以初始化;

  (2)    const常量类的成员变量的初始化必须在构造函数初始化列表中初始化,而不可以在构造函数函数体内初始化。

  (3)  如果其作为C类的成员定义,因为不可以在C类定义创建对象,则可以采用如下措施:

         使用指针,然后在C类的构造函数中,用new 在堆空间创建对象,然后天数const的成员初始化。

  

   此时的const变量属于具体的一个对象,如何在整个类中都恒定不变呢

   答案是利用枚举

#include <iostream>
using namespace std;

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

int main()
{
    A a;
}

  问题说明:

  (1)枚举常量不会占据对象的存储空间,在编译时被全部求值

  (2)但是,它隐含的数据对象类型为整形,不能表示其他类型

2. 必须在构造函数的初始化列表中初始化的情况

  (1)类的const常量;

  (2)类的引用类型成员;

#include <iostream>
using namespace std;

class A
{
    public:
        A(int &v) : i(v), p(v), j(v) {}
        void print_val() { cout << "hello:" << i << "  " << j << endl;}
    private:
        const int i;
        int p;
        int &j;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}

  究其因

  ① const对象或引用只能初始化但是不能赋值。

  ②  构造函数的函数体内只能做赋值而不是初始化,因此初始化const对象或引用的唯一机会是构造函数函数体之前的初始化列表中。

  ③ 明白两个概念:

  从无到有叫初始化,初始化(调用拷贝构造函数)创建了新对象;

  赋值(调用赋值操作符)没有创建新对象,而是对已有的对象赋值。

  (3)没有默认构造函数的类类型成员

#include <iostream>
using namespace std;

class Base
{
    public:
        Base(int a) : val(a) {}
    private:
        int val;
};

class A
{
    public:
        A(int v) : p(v), b(v) {}
        void print_val() { cout << "hello:" << p << endl;}
    private:
        int p;
        Base b;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}

  原因同样是创建对象时,要初始类成员的每一个成员

  (4)如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数;

#include <iostream>
using namespace std;

class Base
{
    public:
        Base(int a) : val(a) {}
    private:
        int val;
};

class A : public Base
{
    public:
        A(int v) : p(v), Base(v) {}
        void print_val() { cout << "hello:" << p << endl;}
    private:
        int p;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}

3. const成员函数

  (1) 任何不修改数据成员的函数都应该声明为const类型。

  如果在编写const成员函数时,①不慎修改了数据成员,②或调用了其他非const成员函数,编译器就会指出错误。应该养成一个好的习惯。

  注意:在const修饰类的成员数据时,一般在const声明在函数声明的后边;

#include <iostream>
using namespace std;
class Stack
{
    public:
        void Push(int item);
        int Pop(void);
        int GetCount(void) const;//const 后置
    private:
        int m_num;
        int m_data[100];
};

int Stack::GetCount(void) const
{
    ++m_num;     //编译错误,企图修改数据成员
    Pop();       //编译错误,企图调用非const函数
    return m_num;
}

  (2)同一个类中,可以仅通过是否是const定义两个函数名字、参数、返回值完全相同的两个成员函数,依据类对象是否为const对象分别调用。

  程序:

#include <iostream>
using namespace std;

class A
{
    public:
        A(int v): val(v) {}
        void print_val() { cout << "not const:" << val << endl;}
        void print_val() const { cout << "const print_val:" << val << endl;}
    private:
        int val;
};
int main(int argc ,char **argv)
{
    A b(45);
    b.print_val();

    const A a(12);
    a.print_val();
}

  输出:

  

  总结:

  同函数名、参数、返回值可以仅通过是否为const来定义为类的两个成员函数。

  在调用时,const对象调用const成员函数,非const对象调用非const成员函数。

4. const的一些问题

  (1)不可以在const函数中改变成员变量的值,那么有没有办法改变?

  答案是可以的,把成员变量声明为mutable类型。看程序

#include <iostream>
using namespace std;

class A
{
    public:
        A(int v): val(v) {}
        void print_val() { cout << "not const:" << val << endl;}
        void print_val() const { val++; cout << "const print_val:" << val << endl;}
    private:
        mutable int val;
};
int main(int argc ,char **argv)
{
    A b(45);
    b.print_val();

    const A a(12);
    a.print_val();
}

  输出:

  

  说明:

  mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。

  在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。

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

  (2)当类中只有const函数,非const对象是否可以调用const函数?

  答案是可以的,范围并没有被扩大。

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

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

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

#include <iostream>
using namespace std;

class A
{
    public:
        A(int v): val(v) {}
        void print_val() { cout << "not const:" << val << endl;}
        void const print_val() const { cout << "const print_val:" << val << endl;}
    private:
        int val;
};
int main(int argc ,char **argv)
{
    A b(45);
    b.print_val();  //非const

    const A *a = new A(45);
    const_cast<A*>(a)->print_val();  //()调用非const的重载函数
    a->print_val();  //调用const的从在函数
}

  输出:

  

  注意;const_cast<A*> (a)只对本地转化有效,且必须使用类的指针进行处理。

  单纯用类转化不行,直接用类的对象不行。

const A a(45);
const_cast<A> a.print_val();

  编译不通过,错误

  (4)返回类型是const是怎么回事?

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

 

  参考网址:

        http://www.cnblogs.com/kaituorensheng/p/3244910.html

时间: 2024-10-14 14:02:13

C++总的const使用说明的相关文章

Python中关于导入(import)语句的使用说明

在所有的语言中,语言的开发者都会为我们提供强大的库文件供我们调用,通过使用这些库文件,我们才可以把程序完美的运行起来,既然要用到库文件,我们就要导入我们需要使用的库文件,因为,机器是不知道我们想基于哪些库进行程序的编写的.在导入库的时候,不同的语言有自己的风格.例如在C/C++等语言中,我们使用#include <>或者#include ""来导入库或者头文件.那么在python中我们怎么导入库呢. 首先,在Python中,我们可以导入三种库:Python标准模块,Pyth

类模板使用说明

类模板声明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //通常形式 template <typename TypeParam> class SomeClass {     //...SomeClass的成员 }; //或者 template <typename TypeParam1,...,typename TypeParamn> class SomeClass {     //...SomeClass的成员 }; 在这些形式中,TypeParam是命名将要

samtools和bcftools使用说明

转自:http://www.cnblogs.com/emanlee/p/4316581.html samtools是一个用于操作sam和bam文件的工具合集.包含有许多命令.以下是常用命令的介绍 1. view view命令的主要功能是:将sam文件转换成bam文件:然后对bam文件进行各种操作,比如数据的排序(不属于本命令的功能)和提取(这些操作 是对bam文件进行的,因而当输入为sam文件的时候,不能进行该操作):最后将排序或提取得到的数据输出为bam或sam(默认的)格式. bam文件优点

Android通用脱壳工具DexHunter的原理分析和使用说明(二)

本文博客地址:http://blog.csdn.net/qq1084283172/article/details/53715325 前面的博文<Android通用脱壳工具DexHunter的原理分析和使用说明(一)>中已经记录了很多关于DexHunter脱壳工具的脱壳原理和思考的思路问题并没有涉及到DexHunter脱壳工具的代码的分析,今天我就代码分析.理解和DexHunter脱壳工具的使用以及需要注意的地方进行博文的记录. 在阅读DexHunter的代码之前,复习下几个须知: 1>.

LibLinear(SVM包)使用说明之(一)README

LibLinear(SVM包)使用说明之(一)README LibLinear(SVM包)使用说明之(一)README [email protected] http://blog.csdn.net/zouxy09 本文主要是翻译liblinear-1.93版本的README文件.里面介绍了liblinear的详细使用方法.更多信息请参考: http://www.csie.ntu.edu.tw/~cjlin/liblinear/ 在这里我用到的是LibLinear的Matlab接口,这个在下一博文

const in C++

const关键字是C++中常用的类型修饰符,用法非常灵活,使用const将大大改善程序的健壮性. const的作用 1.  定义const常量: 比如: const int Max = 100; 2.  便于类型检查: const 常量有数据类型,而宏常量没有数据类型. 编译器对前者进行类型安全检查: 对后者只进行字符替换,没有类型安全检查,在字符替换时可能会产生意料不到的错误. 比如: void func( const int nNum ) {--}  // 对传入的参数进行类型检查,不匹配则

int main (int argc, const char * argv[0]) 中参数的含义;指针数组和数组指针

恩,有的编译器初始化时候会产生这样的参数 argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数是程序的全名 1. 几种C++ 常见的参数种类 int main(void); int main(); int main(int argc, char **argv);   //等价于int main(int argc, char *argv[]),是否等价呢?是不是前一个可以表示任意长度的任意个数组,后一个只是定长的任意个数的数组?见下面 int main(int argc, c

Delphi 中Format的字符串格式化使用说明(转)

源:Delphi 中Format的字符串格式化使用说明(转) 一.Format函数的用法 Format是一个很常用,却又似乎很烦的方法,本人试图对这个方法的帮助进行一些翻译,让它有一个完整的概貌,以供大家查询之用: 首先看它的声明: function Format(const Format: string; const Args: array of const): string; overload; 事实上Format方法有两个种形式,另外一种是三个参数的,主要区别在于它是线程安全的,但并不多用

word2vec中文类似词计算和聚类的使用说明及c语言源代码

word2vec相关基础知识.下载安装參考前文:word2vec词向量中文文本相似度计算 文件夹: word2vec使用说明及源代码介绍 1.下载地址 2.中文语料 3.參数介绍 4.计算相似词语 5.三个词预測语义语法关系 6.关键词聚类 1.下载地址 官网C语言下载地址:http://word2vec.googlecode.com/svn/trunk/ 执行 make 编译word2vec工具: Makefile的编译代码在makefile.txt文件里,先改名makefile.txt 为M