Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

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;
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

书上没有错误,这个初始化语法是拷贝初始化。运行时没有调用拷贝/移动构造函数是因为编译器做了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 *) {}
   ^

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...