C++类的特种函数生成机制详解
什么是特种函数?
C++中存在一些与类相关的函数,它们被称为特种函数。这些特种函数包括:构造函数、析构函数、拷贝构造函数、移动构造函数、拷贝赋值函数、移动赋值函数。这些特殊函数被特别定义,用于实现类的构造、销毁、拷贝和移动操作。
特种函数的生成机制
1. 构造函数
构造函数用于类的实例化过程。类中如果没有定义构造函数,则会生成一个默认构造函数。默认构造函数是没有参数的构造函数,它会在实例化时被调用。
class A {
public:
A() { cout << "default constructor called" << endl; }
};
int main() {
A a; // 调用默认构造函数
return 0;
}
由于默认构造函数没有参数,因此我们无法在实例化时自定义构造函数的参数。当我们定义了自己的构造函数时,即使没有定义默认构造函数,编译器也会默认生成。
2. 析构函数
析构函数用于在销毁类实例时进行清理工作。析构函数的函数名前加了一个波浪号(~
),用于表示它是一个特殊函数。
class A {
public:
A() { cout << "default constructor called" << endl; }
~A() { cout << "destructor called" << endl; }
};
int main() {
{
A a; // 调用构造函数
} // 调用析构函数
return 0;
}
上面的代码中,当a
的作用域结束时,会自动调用析构函数。
3. 拷贝构造函数
拷贝构造函数用于在复制构造函数时用于创建新对象。如果没有定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。
class A {
public:
int data;
A() { cout << "default constructor called" << endl; }
A(const A& other) { data = other.data; cout << "copy constructor called" << endl; }
};
int main() {
A a1;
A a2 = a1; // 调用拷贝构造函数
return 0;
}
上面的代码中,变量a2
的赋值语句会调用a1
的拷贝构造函数,并将值复制给a2
。
4. 移动构造函数
移动构造函数用于实现移动构造语义。移动构造函数也可以由编译器自动生成。
class A {
public:
int data;
A() { cout << "default constructor called" << endl; }
A(A&& other) { data = other.data; cout << "move constructor called" << endl; }
};
int main() {
A a1;
A a2 = std::move(a1); // 调用移动构造函数
return 0;
}
上面的代码中,用std::move
将a1
强制转换为右值,调用移动构造函数生成一个新对象。
5. 拷贝赋值函数
拷贝赋值函数用于在对象赋值时进行数据拷贝。如果没有定义拷贝赋值函数,编译器会自动生成一个默认的拷贝赋值函数。
class A {
public:
int data;
A() { cout << "default constructor called" << endl; }
A& operator=(const A& other) { data = other.data; cout << "copy assign operator called" << endl; return *this; }
};
int main() {
A a1, a2;
a2 = a1; // 调用拷贝赋值函数
return 0;
}
上面的代码中,a2=a1
会调用a2
的拷贝赋值函数,并将a1
的值复制给a2
。
6. 移动赋值函数
移动赋值函数用于在对象移动时进行数据移动。移动赋值函数也可以由编译器自动生成。
class A {
public:
int data;
A() { cout << "default constructor called" << endl; }
A& operator=(A&& other) { data = other.data; cout << "move assign operator called" << endl; return *this; }
};
int main() {
A a1, a2;
a2 = std::move(a1); // 调用移动赋值函数
return 0;
}
上面的代码中,用std::move
将a1
强制转换为右值,调用移动赋值函数并将数据移动到a2
中。
示例说明
示例一
#include<iostream>
using namespace std;
class A
{
public:
int data;
A(int x)
{
data = x;
cout << "构造函数" << endl;
}
~A()
{
cout << "析构函数" << endl;
}
A& operator=(const A& a)
{
data = a.data;
cout << "重载拷贝赋值函数" << endl;
return *this;
}
};
int main()
{
A a1(10);
A a2(20);
A a3(a2);
a1 = a3;
return 0;
}
输出结果:
构造函数
构造函数
构造函数
重载拷贝赋值函数
析构函数
析构函数
析构函数
上面的代码中使用了自定义的构造函数、析构函数和拷贝赋值函数。运行结果可以看出,在定义时调用了构造函数,变量被销毁时调用了析构函数,在赋值时调用了拷贝赋值函数。
示例二
#include<iostream>
using namespace std;
class A
{
public:
int data;
A(int x)
{
data = x;
cout << "构造函数" << endl;
}
~A()
{
cout << "析构函数" << endl;
}
A(A&& a)
{
data = a.data;
cout << "重载移动构造函数" << endl;
}
A& operator=(A&& a)
{
data = a.data;
cout << "重载移动赋值函数" << endl;
return *this;
}
};
void fun(A a)
{
return;
}
int main()
{
A a(10);
fun(std::move(a));
return 0;
}
输出结果:
构造函数
重载移动构造函数
析构函数
析构函数
这个例子展示了移动构造函数和移动赋值函数的用例。在函数调用时,使用std::move
将对象转换为右值,触发了移动构造函数的调用。在函数返回时,a
对象被销毁了,同时触发了移动赋值函数的调用。
总结
特种函数是在类定义中被定义的函数,用于实现类的构造、销毁、拷贝和移动。特种函数可以自己定义,也可以由编译器自动生成。对于每一个函数的生成,编译器都遵循了一定的规则,我们需要了解和掌握这些规则,才能更好地使用它们。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++类的特种函数生成机制详解 - Python技术站