default
c++11 引入 default 特性,多数时候用于声明构造函数为默认构造函数,如果类中有了自定义的构造函数,编译器就不会隐式生成默认构造函数,如下代码:
struct A { int a; A(int i) { a = i; } }; int main() { A a; // 编译出错 return 0; }
上面代码编译出错,因为没有匹配的构造函数,因为编译器没有生成默认构造函数,而通过 default,程序员只需在函数声明后加上“=default;
”,就可将该函数声明为 defaulted 函数,编译器将为显式声明的 defaulted 函数自动生成函数体,如下:
struct A { A() = default; int a; A(int i) { a = i; } }; int main() { A a; return 0; }
编译通过。
delete
c++中,如果开发人员没有定义特殊成员函数,那么编译器在需要特殊成员函数时候会隐式自动生成一个默认的特殊成员函数,例如拷贝构造函数或者拷贝赋值操作符,如下代码:
struct A { A() = default; int a; A(int i) { a = i; } }; int main() { A a1; A a2 = a1; // 正确,调用编译器隐式生成的默认拷贝构造函数 A a3; a3 = a1; // 正确,调用编译器隐式生成的默认拷贝赋值操作符 }
root@ubuntu:~/c++# cat delete.cpp struct A { A() = default; A(const A&) = delete; A& operator=(const A&) = delete; int a; A(int i) { a = i; } }; int main() { A a1; A a2 = a1; // 错误,拷贝构造函数被禁用 A a3; a3 = a1; // 错误,拷贝赋值操作符被禁用 }
root@ubuntu:~/c++# g++ -std=c++11 delete.cpp -o delete delete.cpp: In function ‘int main()’: delete.cpp:11:12: error: use of deleted function ‘A::A(const A&)’ A a2 = a1; // 错误,拷贝构造函数被禁用 ^ delete.cpp:3:5: note: declared here A(const A&) = delete; ^ delete.cpp:13:8: error: use of deleted function ‘A& A::operator=(const A&)’ a3 = a1; // 错误,拷贝赋值操作符被禁用 ^ delete.cpp:4:8: note: declared here A& operator=(const A&) = delete; ^
root@ubuntu:~/c++# cat delete.cpp struct A { A() = default; int a; A(int i) { a = i; } private: A(const A&) {}; A& operator=(const A&) {}; }; int main() { A a1; A a2 = a1; // 错误,拷贝构造函数被禁用 A a3; a3 = a1; // 错误,拷贝赋值操作符被禁用 }
root@ubuntu:~/c++# g++ -std=c++11 delete.cpp -o delete delete.cpp: In function ‘int main()’: delete.cpp:6:5: error: ‘A::A(const A&)’ is private A(const A&) {}; ^ delete.cpp:12:12: error: within this context A a2 = a1; // 错误,拷贝构造函数被禁用 ^ delete.cpp:7:8: error: ‘A& A::operator=(const A&)’ is private A& operator=(const A&) {}; ^ delete.cpp:14:8: error: within this context a3 =
explicit
explicit 专用于修饰构造函数,表示只能显式构造,不可以被隐式转换,根据代码看 explicit 的作用:
不用 explicit:
struct A { A(int value) { // 没有explicit关键字 cout << "value" << endl; } }; int main() { A a = 1; // 可以隐式转换 return 0; }
使用 explicit:
struct A { explicit A(int value) { cout << "value" << endl; } }; int main() { A a = 1; // error,不可以隐式转换 A aa(2); // ok return 0; }