C++中提供类的自定构造函数和编译器提供的默认构造函数区别

C++空类A默认提供三种默认构造函数

#include
using namespace std;
class A
{
public:

};
int main()
{
  A a;
  A b(a);
  A c(std::move(A()));
  c = a; //提供默认的复制重载,和默认的拷贝构造一样是浅拷贝
  return 0;
}
// 有一个需要注意的点:
A a();会被当成一个函数声明,而不是和类有关的
  • 默认构造:inline constexpr A() noexcept = default;
  • 拷贝构造:inline constexpr A(const A &) noexcept = default;
  • 移动构造:inline constexpr A(const A &) noexcept = default;

提供了自定义构造就不会存在默认构造的情况

  • 提供了自定义的默认构造,编译器就不会提供默认的构造函数:
    • 会提供默认的左值拷贝,右值拷贝构造
class A
{
public:
	A(int a){cout<<"A(int)"<<endl;}
};
int main()
{
	A a;//报错,没有对应的默认构造,这种情况只能
	A a1(1);//匹配带参的构造
	A b1(a1);//匹配左值的拷贝构造
	A b(A(1));//等价于 A b = A(1),直接将临时变量优化掉了,直接匹配A(int)构造
	A c(std::move(A(1)));//匹配右值的拷贝构造
	return 0;
}
  • 提供左值拷贝构造,编译器不会提供默认构造,但是必须自己定义个默认构造函数的重载函数,不然不能实例化对象,且编译器不会提供右值构造函数,所有的左右值都匹配左值拷贝
  • 如果提供右值拷贝,不提供左值,编译器也不会提供默认的左值拷贝

总结:

  • 只要提供了任意一种构造函数,编译器都不会提供默认构造函数
  • 如果提供了左值拷贝,编译器不会提供默认的右值构造
  • 如果提供了右值拷贝,编译器就会将默认的左值拷贝进行delete
  • 如果有拷贝构造函数,不提供普通的拷贝构造,是没办法进行对象实例化的,也就是没办法调用拷贝构造

你可能感兴趣的:(c++,算法,开发语言)