拷贝构造函数和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 成员函数的含义

摘录自 <<C++ 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性质.它在编译时,以是否修改成员数据为依据,进行检查.






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值