拷贝构造函数和const成员函数
实验原因
说明如何使用const描述保护类数据不会意外修改.
编译环境
vc6sp6 + win7x64
工程下载
copyConstruction_constMemberFunction.zip
使用非const成员函数,引起的拷贝构造函数报错
- class CStudent
- {
- /// 常量定义
- public:
- enum {NAME_SIZE_MAX = 64};
- /// 构造, 拷贝构造, 析构函数
- public:
- CStudent();
- CStudent(const char* pcName, size_t nId = 1, int iAge = 20);
- CStudent(const CStudent& src);
- virtual ~CStudent();
- /// 成员函数
- public:
- void clear();
- private:
- void init(); ///< 类初始化
- void uninit(); ///< 类反初始化
- void copy(CStudent& src);
- /// setter, getter
- public:
- // m_nId
- void setter_m_nId(size_t nIn) {m_nId = nIn;}
- size_t getter_m_nId() {return m_nId;}
- // m_cName
- void setter_m_cName(const char* pcIn)
- {
- if (NULL == pcIn)
- return;
- memset(m_cName, '\0', NAME_SIZE_MAX);
- strncpy(m_cName, pcIn,
- (strlen(pcIn) < (NAME_SIZE_MAX - 1)) ?
- strlen(pcIn) : (NAME_SIZE_MAX - 1));
- }
- const char* getter_m_cName() {return m_cName;}
- // m_iAge
- void setter_m_iAge(int iIn) {m_iAge = iIn;}
- int getter_m_iAge() {return m_iAge;}
- /// 成员变量
- private:
- size_t m_nId; ///< 学号
- char m_cName[NAME_SIZE_MAX]; ///< 姓名
- int m_iAge; ///< 年龄
- };
- CStudent::CStudent(const CStudent& src)
- {
- copy(src);
- }
- void CStudent::copy(CStudent& src)
- {
- setter_m_cName(src.getter_m_cName());
- setter_m_nId(src.getter_m_nId());
- setter_m_iAge(src.getter_m_iAge());
- }
拷贝构造函数声明为(const class&), 但是拷贝构造函数调用了非const成员函数, 会报错
error C2664: 'copy' : cannot convert parameter 1 from 'const class CStudent' to 'class CStudent &'
如果要查报错资料资料, 查一下关键字.
error C2664: cannot convert parameter 1 from 'const class ' to 'class &'
需要将拷贝构造函数(直接, 简捷)调用的成员函数全部改成const成员函数,
需要将拷贝构造函数调用的成员函数入参为class& 或 class*全部改成 const class& 或 const class*
- class CStudent
- {
- /// 常量定义
- public:
- enum {NAME_SIZE_MAX = 64};
- /// 构造, 拷贝构造, 析构函数
- public:
- CStudent();
- CStudent(const char* pcName, size_t nId = 1, int iAge = 20);
- CStudent(const CStudent& src);
- CStudent(const CStudent* psrc);
- virtual ~CStudent();
- /// 成员函数
- public:
- void clear();
- private:
- void init(); ///< 类初始化
- void uninit(); ///< 类反初始化
- void copy(const CStudent* psrc);
- /// setter, getter
- public:
- // m_nId
- void setter_m_nId(size_t nIn) {m_nId = nIn;}
- size_t getter_m_nId() const {return m_nId;}
- // m_cName
- void setter_m_cName(const char* pcIn)
- {
- if (NULL == pcIn)
- return;
- memset(m_cName, '\0', NAME_SIZE_MAX);
- strncpy(m_cName, pcIn,
- (strlen(pcIn) < (NAME_SIZE_MAX - 1)) ?
- strlen(pcIn) : (NAME_SIZE_MAX - 1));
- }
- const char* getter_m_cName() const {return m_cName;}
- // m_iAge
- void setter_m_iAge(int iIn) {m_iAge = iIn;}
- int getter_m_iAge() const {return m_iAge;}
- /// 成员变量
- private:
- size_t m_nId; ///< 学号
- char m_cName[NAME_SIZE_MAX]; ///< 姓名
- int m_iAge; ///< 年龄
- };
- CStudent::CStudent(const CStudent& src) ///< 入参改成const class&
- {
- copy(&src);
- }
- CStudent::CStudent(const CStudent* psrc)
- {
- copy(psrc);
- }
- void CStudent::copy(const CStudent* psrc)
- {
- setter_m_cName(psrc->getter_m_cName());
- setter_m_nId(psrc->getter_m_nId());
- setter_m_iAge(psrc->getter_m_iAge());
- }
const 成员函数的含义
http://blog.csdn.net/zhuanshenweiliu/article/details/38223907
3. const成员函数
任何不会修改数据成员(即函数中的变量)的函数都应该声明为const类型。
如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。
以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数。编译器将指出GetCount函数中的错误。
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; // const成员函数
private:
int m_num;
int m_data[100];
} ;
int Stack::GetCount(void) const
{
++ m_num; //编译错误,企图修改数据成员m_num
Pop(); //编译错误,企图调用非const函数
return m_num;
}
const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
关于Const函数的几点规则:
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
http://blog.csdn.net/lostspeed/article/details/50291749
拷贝构造函数和const成员函数的更多相关文章
- C++类的const成员函数、默认的构造函数、复制形参调用函数(转)
C++类的const成员函数 double Sales_item::avg_price() const { } const关键字表明这是一个const成员函数,它不可以修改Sales_item类的成员 ...
- 12.C++-构造函数与析构函数调用顺序,const成员函数,const对象
单个对象创建时,构造函数的调用顺序 1.首先判断该对象的类是否拥有父类,若有则先调用父类的构造函数 2.判断该对象的成员是否是其它类的成员,若是则调用成员变量的构造函数(调用顺序和声明顺序相同) 3. ...
- 【C++】拷贝构造函数和赋值符函数
在C++中,调用拷贝构造函数有三种情况: 1.一个对象作为函数参数,以值传递的方式传入函数体. 2.一个对象作为函数返回值,以值传递的方式从函数返回. 3.一个对象用于给另外一个对象进行初始化(复制初 ...
- c++ 学习之const专题之const成员函数
一些成员函数改变对象,一些成员函数不改变对象. 例如: int Point::GetY() { return yVal; } 这个函数被调用时,不改变Point对象,而下面的函数改变Point对象: ...
- C++ Const成员函数
一些成员函数改变对象,一些成员函数不改变对象. 例如: int Point::GetY() { return yVal; } 这个函数被调用时,不改变Point对象,而下面的函数改变Point对象 ...
- c++中的const参数,const变量,const指针,const对象,以及const成员函数
const 是constant 的缩写,“恒定不变”的意思.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.所以很多C++程序设计书籍建议:“Use const whe ...
- (转)函数后面加const--C++ const成员函数
类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于 ...
- 类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)
假设我们要设计一个包含以下操作的 Sales_data 类: 1.一个 isbn 成员函数,用于返回对象的 book_no 成员变量 2.一个 combine 成员函数,用于将一个 Sales_dat ...
- const成员函数
尽管函数名和参数列表都相同,void foo( ) const成员函数是可以与void foo( )并存的,可以形成重载! 我们假设调用语句为obj.foo(),如果obj为non-const对象,则 ...
随机推荐
- 【UVA】658 - It's not a Bug, it's a Feature!(隐式图 + 位运算)
这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 < ...
- [置顶] NGINX原理分析之SLAB分配机制
一.基础概述 如果使用伙伴系统分配和释放算法,不仅会造成大量的内存碎片,同时处理效率也比较低.SLAB是一种内存管理机制,其核心思想是预分配.SLAB是将空间按照SIZE对内存进行分类管理的,当申请一 ...
- server配置学习 ---- 关闭防火墙
iptables 一种网络防火墙,在LINUX下使用,RedHat9.0版本号以上自带. 它能够实现NAT转换.能够做上网代理. 首先对于server的配置第一步来说就是关闭防火墙.在没有图形化中的l ...
- STL之Queue(Q)
STL的Queue(数据结构中的队列): 特点:FIFO 先进先出: 自适应容器(即容器适配器) 栈适配器STL queue STL中实现的Queue: 用list来实现queue: queue ...
- BZOJ 2431: [HAOI2009]逆序对数列( dp )
dp(i,j)表示1~i的全部排列中逆序对数为j的个数. 从1~i-1的全部排列中加入i, 那么可以产生的逆序对数为0~i-1, 所以 dp(i,j) = Σ dp(i-1,k) (j-i+1 ≤ k ...
- c语言详解 蔡勒(Zeller)公式计算某一天是星期几 极其方便
—— 蔡勒(Zeller)公式 ,小于等于14,即在蔡勒公式中,某年的1.2月要看作上一年的13.14月来计算,比如2003年1月1日要看作2002年的13月1日来计算):d:日:[ ]代表取整,即只 ...
- HttpResponseRedirect VS HttpResponse
当我们处理了post提交的数据之后,我们使用HttpResponseRedirect跳转到另一个页面,而不是用HttpResponse. 例如当一个投票环节时使用HttpResponse可以使用浏览器 ...
- Windows Phone 8初学者开发—第16部分:使用应用程序栏
原文 Windows Phone 8初学者开发—第16部分:使用应用程序栏 原文地址: http://channel9.msdn.com/Series/Windows-Phone-8-Develop ...
- 管理tips
管理是什么? 我认为达到的目的就是高效.低成本. 成本低才能有盈余,才能活的长和舒服.高效就是无谓的消耗少,以结果为导向. 开源节流,应该包含显性的与隐性的两方面. 隐性成本: 1.会议成本;2.沟通 ...
- EditText 软键盘
EditText 软键盘 package brother.eighteen.demoedittext; import android.content.Context; import android.t ...