1. 类与默认函数:
C++中声明自定义的类,编译器会默认生成未定义的成员函数:
构造函数
拷贝构造函数
拷贝赋值函数(operator=)
移动构造函数
移动拷贝函数
析构函数
编译器还会提供全局默认操作符函数:
operator,
operator &
operator &&
operator *
operator ->
operator ->*
operator new
operator delete
2. default delete
#include <type_traits> #include <iostream> using namespace std; class NoCopyCator { public: NoCopyCator() = default; NoCopyCator(const NoCopyCator&) = delete; //阻止使用拷贝构造函数 }; int main() { NoCopyCator a; NoCopyCator b(a); //无法通过编译 return 0; }
=default修饰的函数为显式缺省函数
=delete修饰的函数为删除函数
delete可以避免一些不必要的隐式数据类型转换。
class ConvType { public: ConvType(int i) {} ConvType(char c) = delete; }; void Func(ConvType ct) {} int main() { Func(3); Func('a'); //无法通过编译 ConvType ci(3); ConvType cc('a'); //无法通过编译 return 0; }
//delete 不局限于缺省版本的类成员函数或者全局函数,对于普通的函数也可以通过显式删除来禁止类型转换
void Func(int i) {}
void Func(char c) = delete;
int main() {
Func(3);
Func('c'); //无法通过编译
return 1;
}
显示删除可以删除自定义类型的operator new操作来避免在堆上分配该class对象。
#include <cstddef> class NoHeapAlloc { void* operator new(std::size_t) = delete; }; int main() { NoHeapAlloc nha; NoHeapAlloc* pnha = new NoHeadAlloc; //编译失败 return 0; }
如果需要在指定内存位置进行内存分配,并且不需要析构函数来完成一些对象级别的清理。可以通过显示删除析构函数来限制自定义类型在栈上或者静态的构造。
#include <cstddef> #include <new> extern void* p; class NoStackAlloc { public: ~NoStackAlloc() = delete; }; int main() { NoStackAlloc nsa; //无法通过编译 new (p) NoStackAlloc(); // placement new, 假设p无需调用析构函数 return 0; }