如何理解复制构造函数

How to understand copy-constructior function?

本文关键字:构造函数 复制 何理解      更新时间:2023-10-16
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    class String{
    public:
            String(){}
            String(const char *ptr)
            {
                    pstr_= new char[strlen(ptr) + 1];
                    strcpy(pstr_,ptr);
            }
            String(const String &str)
            {
                    strcpy(this->pstr_,str.get_pstr());
            }
            ~String()
            {
                    delete pstr_ ;
            }
            char *get_pstr()
            {
                    return pstr_ ;
            }
    private:
            char *pstr_ ;
    };
    int main(int argc,char *argv[])
    {
            char *sh = "Hello World";
            String str(sh) ;
            String st(str) ;
            std::cout << str.get_pstr() << std::endl ;
            return 0 ;
    }

对不起,我的英语不好,帮助你理解我的意思。我写了这样的代码.我确定这是正确的.但是,它会产生隔离错误。所以,我发现了一个奇怪的现象 gdb.

38              std::cout << str.get_pstr() << std::endl ;
(gdb) n
Breakpoint 1, String::get_pstr (this=0x7fffffffe470) at String.cpp:26
26                      return pstr_ ;
(gdb) n
27              }
(gdb) n
Hello World
main (argc=1, argv=0x7fffffffe578) at String.cpp:40
40              return 0 ;
(gdb) n
37              String st(str) ;
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7282ba1 in __strlen_sse2 () from /lib64/libc.so.6

当程序运行时返回0,它可以重新运行字符串st(str)。 我很担心。帮你解释一下。谢谢!

所以,这里有两个问题。

崩溃是由于您没有在复制构造函数中分配新内存。将其与在复制字符串之前正确执行此操作的普通构造函数进行比较。

第二个问题是 gdb 在这种情况下以令人困惑的方式行事。您可能通过某种程度的优化编译了代码,以便允许编译器对指令进行重新排序。由于在 cout 打印期间不需要复制构造的字符串,因此由于某种原因它被移过它,这就是 gdb 向您展示的内容。尝试在不进行优化的情况下重新编译代码,您应该会看到指令按照编写它们的顺序执行。

您还应该在复制构造函数中分配内存:

String(const String &str)
{
    pstr_= new char[strlen(ptr.get_pstr()) + 1];
    strcpy(this->pstr_,str.get_pstr());
}

或:

String(const String &str): String(str.get_pstr()) { }