C++的編譯器會給一個空的類提供六個函式
- 預設建構函式
- 解構函式
- 複製構造
- 複製賦值
- 移動構造
- 移動賦值
在提供建構函式時,編譯器將不再提供預設構造
這些函式在物件傳參、返回物件、接收物件時會自動呼叫,所以有必要進行相應的最佳化,減少這種隱式呼叫
以下面這段程式碼為例:
#include <iostream>
class Foo {
public:
Foo(int a) : _a(a) { std::cout << "Foo(int)" << std::endl; }
~Foo() { std::cout << "~Foo()" << std::endl; }
Foo(const Foo &val) : _a(val._a) {
std::cout << "Foo(const Foo&)" << std::endl;
}
Foo(Foo &&val) : _a(val._a) { std::cout << "Foo(Foo&&)" << std::endl; }
Foo &operator=(const Foo &val) {
if (this == &val)
return *this;
_a = val._a;
return *this;
}
Foo &operator=(Foo &&val) {
if (this == &val)
return *this;
_a = val._a;
return *this;
}
int getA() const { return _a; }
private:
int _a;
};
Foo bar(Foo f) { // 3. Foo(const Foo&)
int a = f.getA();
Foo tmp(a);
return tmp;
}
Foo bar2(const Foo &f) { return Foo{f.getA()}; }
int main() {
{
Foo f1(42); // 1. Foo(int)
Foo f2(10); // 2. Foo(int)
f2 = bar(f1); // 4. Foo(int)
}
std::cout << "============================" << std::endl;
{
Foo f3(42); // 1. Foo(int)
Foo f4 = bar2(f3); // 2. Foo(int)
}
}
執行結果如下:
eric@eric-XPS-13-9360:~/tmp$ g++ main.cpp
eric@eric-XPS-13-9360:~/tmp$ ./a.out
Foo(int)
Foo(int)
Foo(const Foo&)
Foo(int)
~Foo()
~Foo()
~Foo()
~Foo()
============================
Foo(int)
Foo(int)
~Foo()
~Foo()