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