让我们表演和讲述,让我们为所有特殊成员提供乐器:
#include <iostream>
class abc{
public:
int a, b;
abc()
{ std::cout << "Default constructor\n"; a = 0; b = 0;}
abc(int x)
{ std::cout << "Int constructor\n"; a = x;}
abc(abc const& other): a(other.a), b(other.b)
{ std::cout << "Copy constructor (" << a << ", " << b << ")\n"; }
abc& operator=(abc const& other) {
std::cout << "Assignment operator (" << a << ", " << b << ") = (" << other.a << ", " << other.b << ")\n";
a = other.a;
b = other.b;
return *this;
}
~abc()
{std::cout << "Destructor Called\n";}
};
int main()
{
abc obj1;
std::cout << "OBJ1 " << obj1.a << "..." << obj1.b << "\n";
abc obj2;
std::cout << "OBJ2 " << obj2.a << "..." << obj2.b << "\n";
obj2 = 100;
std::cout << "OBJ2 " << obj2.a << "\n";
return 0;
}
我们得到this output:
Default constructor
OBJ1 0...0
Default constructor
OBJ2 0...0
Int constructor
Assignment operator (0, 0) = (100, 0)
Destructor Called
OBJ2 100
Destructor Called
Destructor Called
所以,让我们将它们与线源相协调:
int main()
{
abc obj1;
// Default constructor
std::cout << "OBJ1 " << obj1.a << "..." << obj1.b << "\n";
// OBJ1 0...0
abc obj2;
// Default constructor
std::cout << "OBJ2 " << obj2.a << "..." << obj2.b << "\n";
// OBJ2 0...0
obj2 = 100;
// Int constructor
// Assignment operator (0, 0) = (100, 0)
// Destructor Called
std::cout << "OBJ2 " << obj2.a << "\n";
// OBJ2 100
return 0;
// Destructor Called
// Destructor Called
}
你基本上已经拥有了一切,让我们来看看惊喜。
第一个惊喜:即使 obj2 稍后更改值 abc obj2; 仍会在声明时调用默认构造函数。
第二个惊喜:obj2 = 100其实就是obj2.operator=(abc(100));的意思,也就是:
- 从
abc(100) 构建一个临时(未命名)abc
- 将其分配给
obj2
- 在继续下一条语句之前销毁临时文件
第三个惊喜:析构函数在作用域的末尾被调用,就在右括号} 之前(是的,在return 之后)。由于您使用的是system("pause"),因此我假设您在 Windows => 尽管幸运的是,它们在您结束暂停后被调用,因此您的控制台 Windows 在它们出现的那一刻就消失了。您可以从更永久的控制台启动程序,也可以使用额外的范围:
int main () {
{
// your code here
}
system("pause");
return 0;
}