VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 296|回复: 6

[讨论] 拷贝构造函数求解

[复制链接]
46_avatar_middle
最佳答案
0 
在线会员 发表于 2022-1-12 14:04:10 | 显示全部楼层 |阅读模式
1.拷贝构造函数与普通构造函数的异同
2.何种情况下,拷贝构造函数被调用
3.其他注意事项

望大神解答!




上一篇:莫问剑 -WINDOWS 应用、系统编程(待续)记录学习之路
下一篇:莫问剑 WINDOWS 应用、系统编程(待续)窗口过程完结记录
46_avatar_middle
最佳答案
1 
在线会员 发表于 5 天前 | 显示全部楼层
本帖最后由 screen_ok 于 2022-1-16 09:11 编辑

1、拷贝构造函数也是会被自动调用的:

string s1(const string& ss)
{
        string sss = ss.substr(2, 5);
        return sss;
}

这里返回的 sss 就会调用拷贝构造函数。因为局部变量(sss)在函数返回后就被销毁(在栈上创建的)了,需要在一个特殊的地方创建一个string对象,复制sss的值,然后才能进行后续操作。

2、一般情况下拷贝构造函数是由编译器实现(值对拷)的,自己实现拷贝构造函数多数是因为类内含有指针型变量,需要自己定义拷贝时的行为。比如:

        pszs1 = pszs2;  pszs1, pszs2都是指针。这种叫做浅拷贝。这种操作效率高,但是要通引用计数等方法防止出错;

        strcpy(pszs1, pszs2); 这种叫做深拷贝,安全一些,但是慢。比如用来操作两幅大的位图的话速度肯定是无法忍受的。

所以才会有建议说用 vector 代替数组,用 string 代替字符串,尽量减少指针的使用,就是为了减轻开发和维护时负担。
17_avatar_middle
最佳答案
10 
在线会员 发表于 2022-1-12 18:43:23 | 显示全部楼层
三种情况下会调用拷贝构造函数:

使用一个已经创建完毕的对象来初始化另一个新对象。
值传递的方式给函数参数传值。
以值方式返回局部对象。
07_avatar_middle
最佳答案
10 
在线会员 发表于 2022-1-12 15:44:33 | 显示全部楼层
普通构造函数:根据构造函数的参数,构造出一个对象。
拷贝构造函数:根据本类的一个对象,构造出本类的另一个对象。

拷贝,就是复制的意思,既然是复制,那就需要先有一个对象,然后才能复制这个对象。被复制的这个对象可能来自于普通构造函数。

在C++11里,需要和移动语义区分。
20_avatar_middle
最佳答案
0 
在线会员 发表于 2022-1-12 16:05:56 | 显示全部楼层
本帖最后由 zhengl33 于 2022-1-12 16:48 编辑

举列说明:
class CTest
{
public:
            CTest() : m_num(0), m_szpStr(NULL) { }                        ///无参数构造函数

            CTest(int num) : m_num(num),  m_szpStr(NULL) { }     ///一个参数构造函数

            CTest(int num, char* szpStr) : m_num(num)                ///两个参数构造函数
            {
                if( szpStr )
              {
                  int len = strlen(szpStr);
                  m_szpStr = new char[len + 1]{0};
                  strcpy(m_szpStr, szpStr);
                }
                else
                      m_szpStr = NULL;
            }

            CTest(CTest& Test) : m_num(Test.m_num)                    ///拷贝构造函数
            {
                if( Test.m_szpStr )
              {
                  int len = strlen(Test.m_szpStr);
                  m_szpStr = new char[len + 1]{0};
                  strcpy(m_szpStr, Test.m_szpStr);
                }
                else
                      m_szpStr = NULL;
            }

private:
           int     m_num;
           char* m_szpStr;
}

1.
普通构造函数:参数可以你自己定义,可以没有,也可以多个。例如CTest()、 CTest(int num) 与 CTest(int num, char* szpStr)。
拷贝构造函数:参数只能为一个本类的对象。例如: CTest(CTest& Test);

2.
拷贝构造函数,不会自动调用,你需要调用的时候调用。
比如调用的时候:
CTest test1();
CTest test2(num);                 //num为实参。
CTest test3(num,str);        //str为实参。
CTest test4(test1);
调用时几种写法都是可以的。

3.
注意:
通常情况下(无实际代码,不好判断,只能说通常情况),指针类型成员变量,例如char* 不能直接用 = 赋值,需要拷贝,不然很容易引起内存泄漏。
至于C++11 和移动语义区分,建议去看看 移动构造函数 的教程。
46_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 6 天前 | 显示全部楼层
freehawkzk 发表于 2022-1-12 15:44
普通构造函数:根据构造函数的参数,构造出一个对象。
拷贝构造函数:根据本类的一个对象,构造出本类的另 ...

好的,明白了
46_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 6 天前 | 显示全部楼层
zhengl33 发表于 2022-1-12 16:05
举列说明:
class CTest
{

好的,非常详细了
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2022-1-21 10:27

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表