让我们表演和讲述,让我们为所有特殊成员配备乐器:
#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;
}
我们得到这个输出:
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
)abc(100)
- 分配给
obj2
- 在继续下一条语句之前销毁临时
第三个惊喜:析构函数在作用域的末尾被调用,就在右括号之前}
(是的,在之后return
)。由于您使用的是system("pause")
我假设您在 Windows => 虽然幸运,但它们在您结束暂停后被调用,因此您的控制台 Windows 在它们出现的那一刻消失在眨眼之间。您可以从更永久的控制台启动程序,或使用额外的范围:
int main () {
{
// your code here
}
system("pause");
return 0;
}