天天看點

C++11新特性之 default and delete

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

繼續閱讀