const成员变量

举个例子

#include <iostream>
using namespace std; class A
{
public:
A(int size) : SIZE(size) {};
private:
const int SIZE;
}; int main()
{
A a();
}

说明

  • 在类中声明变量为const类型,但是不可以初始化
  • const常量的初始化必须在构造函数初始化列表中初始化,而不可以在构造函数函数体内初始化

但是

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

答案是利用枚举,举例

#include <iostream>
using namespace std; class A
{
private:
enum {SIZE = };
public:
int array[SIZE];
}; int main()
{
A a;
}

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

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

问题

如何定义在类中定义非整形常量?(待解决)

话说有几个地方必须在构造函数的初始化列表中(详见):

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

const成员函数

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

示例说明

#include <iostream>
using namespace std;
class Stack
{
public:
void Push(int item);
int Pop(void);
int GetCount(void) const;
private:
int m_num;
int m_data[];
}; int Stack::GetCount(void) const
{
++m_num; //编译错误,企图修改数据成员
Pop(); //编译错误,企图调用非const函数
return m_num;
}

同一个类中,可以仅通过是否是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();
b.print_val(); const A a();
a.print_val();
}

输出

结论

同函数名、参数、返回值可以仅通过是否为const来定义为类的两个成员函数。在调用时,const对象调用const成员函数,非const对象调用非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();
b.print_val(); const A a();
a.print_val();
}

结果

问题2:

当类中只有const函数,非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 { val++; cout << "const print_val:" << val << endl;}
private:
mutable int val;
};
int main(int argc ,char **argv)
{
A b();
b.print_val(); const A a();
a.print_val();
}

结果

但是:还有非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();
b.print_val(); const A *a = new A();
const_cast<A*>(a)->print_val();
a->print_val();
}

结果

注意

单纯用类转化不行

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

报错

问题4:返回类型是const是怎么回事?

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

【c++】类中的const成员的更多相关文章

  1. C++ 类中的const关键字

    //类中的const关键字 #include<iostream> using namespace std; class Point{ public: //这个const关键字本质上修饰的是 ...

  2. C++ 类中的static成员的初始化和特点

    C++ 类中的static成员的初始化和特点 #include <iostream> using namespace std; class Test { public: Test() : ...

  3. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  4. C++类中的常成员和静态成员

    常变量.常对象.常引用.指向常对象或常变量的指针等在定义时都使用了const关键字,这是C++语言引入的一种数据保护机制,称为const数据保护机制.例如通过const关键字主动地将被调函数形参进行限 ...

  5. 在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static

    在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create ...

  6. C++ —— 非类中使用const定义常量的初始化,以及#define和typedef的区别

    总结一下在非类中使用const关键字定义常量时的初始化问题,亲测VS2015.顺便记录#define宏和typedef的区别. 1 首先对const声明的常量的初始化做简单小结: , w2 = , w ...

  7. 类中的internal成员可能是一种坏味道

    前言 最近除了搞ASP.NET MVC之外,我也在思考一些编程实践方面的问题.昨天在回家路上,我忽然对一个问题产生了较为清晰的认识.或者说,原先只是有一丝细微的感觉,而现在将它和一些其他的方面进行了联 ...

  8. c++:类中的static成员

    首先静态成员可以是public的,也可以是private的,只需在一般的变量.函数声明语句前加上static关键字即可声明一个static变量. 类中的静态成员存在与任何对象之外,所有该类对象的共享一 ...

  9. C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法

    有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同.这些特殊的类型的成员变量包括: a.引用 b.常量 c.静态 d.静态常量(整型) e.静态常量(非整型) 常量和引 ...

随机推荐

  1. Unity3d中使用Lua

    对于手机游戏,如果可以在线更新以实现bug修复.新功能添加等等,其好处自不必多说. 通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考 http://docs.unity3d.com/ ...

  2. 微服务编译、启动jar命令指定配置文件

    nohup java -Xms512m -Xmx8g -Xmn512m -Xss512k -server -XX:+HeapDumpOnOutOfMemoryError -jar smp-bill-c ...

  3. asp.net——上传图片生成缩略图

    上传图片生成缩略图,原图和缩略图地址一样的时候缩略图会把原图覆盖掉 /// <summary> /// 生成缩略图 /// </summary> /// <param n ...

  4. ({i:0#.w|nt authority\iusr})Sharepoint impersonates the IUSR account and is denied access to resources

    This hotfix makes a new application setting available in ASP.NET 2.0. The new application setting is ...

  5. javascript实现八大排序

    开学一个月,已经多次梦见笔试出现数据结构算法题,我对数据结构的恐惧已经多于任何“妖魔鬼怪”了.呵呵,看来真的很有必要复习一下常用的数据结构,免得“噩梦”成真. 数据机构等编程基础的重要性不用多说,直接 ...

  6. CF834D The Bakery

    题目链接:戳我 题意:将一个长度为n的序列分为k段,使得总价值最大.一段区间的价值表示为区间内不同数字的个数 \(n<=35000,k<=50\) 开始想的转移方程是这个样子的--\(dp ...

  7. JAVA中的static关键字(静态变量和成员变量)

    static的特点: 1.static是一个修饰符,用于修饰成员: 2.static修饰的成员被所有的对象所共享: 3.static优先于对象存在,因为static的成员随着类的加载就已经存在了: 4 ...

  8. [CISCO] 转载:冲突域与广播域(区别、知识要点)

    [CISCO] 转载:冲突域与广播域(区别.知识要点) 1.传统以太网操作(Ethernet Connection Ethernet) 传统共享式以太网的典型代表是总线型以太网.在这种类型的以太网中, ...

  9. P5242 [USACO19FEB]Cow Dating

    题目链接 题意分析 首先我们可以得出计算公式 \[s_i=\prod_{k=1}^i(1-p_k)\] \[f_i=\sum_{k=1}^i\frac{p_k}{1-p_k}\] 那么 \[ans(i ...

  10. Ubuntu16.04安装视觉SLAM环境(OpenCV)

    一.安装依赖库 sudo apt-get install build-essential sudo apt--dev pkg-config libavcodec-dev libavformat-dev ...