首頁  >  問答  >  主體

C++拷贝构造函数:C++ Primer

itemStr it_str = "123456";

这样的代码应该是拷贝初始化?如果是拷贝初始化,那么在C++ Primer 中文版第五版中441页提到

拷贝初始化是依靠拷贝构造函数或移动构造函数来往成的

但是实际调用的却是itemStr(const char *s)

这是为什么,是书的错误还是编译器的优化操作

itemStr类,如上所写会输出This is normal constructor2.

class itemStr
{
public:
    itemStr() :
        str()
    {
        std::cout << "This is default constructor." << std::endl;
    }

    itemStr(std::string s) :
        str(s)
    {
        std::cout << "This is normal constructor1." << std::endl;
    }

    itemStr(const char *s) :
        str(s)
    {
        std::cout << "This is normal constructor2." << std::endl;
    }
    itemStr(const itemStr &it) :
        str(it.str)
    {
        std::cout << "This is copy constructor." << std::endl;
    }

    itemStr& operator=(const itemStr &it)
    {
        str = it.str;
        std::cout << "This is copy-assignment operator constructor." << std::endl;
        return *this;
    }

private:
     std::string str;
};
PHP中文网PHP中文网2764 天前566

全部回覆(1)我來回復

  • 黄舟

    黄舟2017-04-17 15:40:26

    書上沒有錯誤,這個初始化語法就是拷貝初始化。運行時沒有呼叫拷貝/移動建構函數是因為編譯器做了copy elision最佳化。即便在拷貝/移動建構函數有可見的副作用時,編譯器仍被允許進行這種最佳化。結果就是你無法觀察到期望的輸出。

    也就是說itemStr it_str = "123456";是拷貝初始化,它的確需要一個可用的拷貝/移動建構函數。以下程式碼在gcc/clang下編譯會報編譯錯誤。

    class A {
     public:
      A(const char *) {}
    
      A(const A &) = delete;
      A(A &&) = delete;
    };
    
    int main() {
      A x = "abc";
      return 0;
    }
    

    main.cc: In function ‘int main()’:
    main.cc:12:9: error: use of deleted function ‘A::A(A&&)’
       A x = "abc";
             ^
    main.cc:8:3: note: declared here
       A(A &&) = delete;
       ^
    main.cc:5:3: note:   after user-defined conversion: A::A(const char*)
       A(const char *) {}
       ^

    回覆
    0
  • 取消回覆