• 拷贝构造函数和const成员函数


    实验原因

    说明如何使用const描述保护类数据不会意外修改. 

    编译环境

    vc6sp6 + win7x64

    工程下载

            copyConstruction_constMemberFunction.zip

     

    使用非const成员函数,引起的拷贝构造函数报错

    [cpp] view plain copy
     
    1. class CStudent    
    2. {  
    3.     /// 常量定义  
    4. public:  
    5.     enum {NAME_SIZE_MAX = 64};  
    6.   
    7.     /// 构造, 拷贝构造, 析构函数  
    8. public:  
    9.     CStudent();  
    10.     CStudent(const char* pcName, size_t nId = 1, int iAge = 20);  
    11.     CStudent(const CStudent& src);  
    12.     virtual ~CStudent();  
    13.   
    14.     /// 成员函数  
    15. public:  
    16.     void clear();  
    17.   
    18. private:  
    19.     void init(); ///< 类初始化  
    20.     void uninit(); ///< 类反初始化  
    21.     void copy(CStudent& src);  
    22.   
    23.     /// setter, getter  
    24. public:  
    25.     // m_nId  
    26.     void setter_m_nId(size_t nIn) {m_nId = nIn;}  
    27.     size_t getter_m_nId() {return m_nId;}  
    28.   
    29.     // m_cName  
    30.     void setter_m_cName(const char* pcIn)  
    31.     {  
    32.         if (NULL == pcIn)  
    33.             return;  
    34.   
    35.         memset(m_cName, '', NAME_SIZE_MAX);  
    36.         strncpy(m_cName, pcIn,   
    37.             (strlen(pcIn) < (NAME_SIZE_MAX - 1)) ?   
    38.             strlen(pcIn) : (NAME_SIZE_MAX - 1));  
    39.     }  
    40.   
    41.     const char* getter_m_cName() {return m_cName;}  
    42.   
    43.     // m_iAge  
    44.     void setter_m_iAge(int iIn) {m_iAge = iIn;}  
    45.     int getter_m_iAge() {return m_iAge;}  
    46.   
    47.     /// 成员变量  
    48. private:  
    49.     size_t m_nId; ///< 学号  
    50.     char m_cName[NAME_SIZE_MAX]; ///< 姓名  
    51.     int m_iAge; ///< 年龄  
    52. };  
    [cpp] view plain copy
     
    1. CStudent::CStudent(const CStudent& src)  
    2. {  
    3.     copy(src);  
    4. }  
    5.   
    6. void CStudent::copy(CStudent& src)  
    7. {  
    8.     setter_m_cName(src.getter_m_cName());  
    9.     setter_m_nId(src.getter_m_nId());  
    10.     setter_m_iAge(src.getter_m_iAge());  
    11. }  

    拷贝构造函数声明为(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*

    [cpp] view plain copy
     
    1. class CStudent    
    2. {  
    3.     /// 常量定义  
    4. public:  
    5.     enum {NAME_SIZE_MAX = 64};  
    6.   
    7.     /// 构造, 拷贝构造, 析构函数  
    8. public:  
    9.     CStudent();  
    10.     CStudent(const char* pcName, size_t nId = 1, int iAge = 20);  
    11.     CStudent(const CStudent& src);  
    12.     CStudent(const CStudent* psrc);  
    13.     virtual ~CStudent();  
    14.   
    15.     /// 成员函数  
    16. public:  
    17.     void clear();  
    18.   
    19. private:  
    20.     void init(); ///< 类初始化  
    21.     void uninit(); ///< 类反初始化  
    22.     void copy(const CStudent* psrc);  
    23.   
    24.     /// setter, getter  
    25. public:  
    26.     // m_nId  
    27.     void setter_m_nId(size_t nIn) {m_nId = nIn;}  
    28.     size_t getter_m_nId() const {return m_nId;}  
    29.   
    30.     // m_cName  
    31.     void setter_m_cName(const char* pcIn)  
    32.     {  
    33.         if (NULL == pcIn)  
    34.             return;  
    35.   
    36.         memset(m_cName, '', NAME_SIZE_MAX);  
    37.         strncpy(m_cName, pcIn,   
    38.             (strlen(pcIn) < (NAME_SIZE_MAX - 1)) ?   
    39.             strlen(pcIn) : (NAME_SIZE_MAX - 1));  
    40.     }  
    41.   
    42.     const char* getter_m_cName() const {return m_cName;}  
    43.   
    44.     // m_iAge  
    45.     void setter_m_iAge(int iIn) {m_iAge = iIn;}  
    46.     int getter_m_iAge() const {return m_iAge;}  
    47.   
    48.     /// 成员变量  
    49. private:  
    50.     size_t m_nId; ///< 学号  
    51.     char m_cName[NAME_SIZE_MAX]; ///< 姓名  
    52.     int m_iAge; ///< 年龄  
    53. };  
    [cpp] view plain copy
     
    1. CStudent::CStudent(const CStudent& src) ///< 入参改成const class&  
    2. {  
    3.     copy(&src);  
    4. }  
    5.   
    6. CStudent::CStudent(const CStudent* psrc)  
    7. {  
    8.     copy(psrc);  
    9. }  
    10.   
    11. void CStudent::copy(const CStudent* psrc)  
    12. {  
    13.     setter_m_cName(psrc->getter_m_cName());  
    14.     setter_m_nId(psrc->getter_m_nId());  
    15.     setter_m_iAge(psrc->getter_m_iAge());  
    16. }  



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

    http://blog.csdn.net/lostspeed/article/details/50291749

  • 相关阅读:
    在人生路上对我影响最大的三位老师
    秋季学期学习总结
    转载非原创 Windows编程革命简史
    转载 关于12360系统的讨论
    SQLServer 触发器
    sqlserver 自定义函数
    jQuery 动画
    jQuery让页面生动起来(操作页面里面的元素)
    jQuery选择元素
    SqlServer_Case_When用法
  • 原文地址:https://www.cnblogs.com/findumars/p/5187284.html
Copyright © 2020-2023  润新知