Administrator
Administrator
发布于 2025-11-08 / 5 阅读
0
0

移除class构造的一些行为

1.

class Base {
public:
	Base(Base& other) = delete;
};
//或
class Base {
public:
	Base(Base&& other) = delete;
};

移除拷贝构造或移动构造时,拷贝构造、移动构造、空构造都会被移除,用哪个就要手动补回来:

class Base {
public:
	Base() = default;
	Base(Base&& other) = default;

	Base(Base& other) = delete;
};

2.

class Base {
public:
	Base() = delete;
};

移除空构造时,拷贝构造和移动构造依然保持默认实现,不会受影响

没有拷贝构造的影响

  1. 传递左值时,必须要转成左值引用,因为无法发生拷贝得到副本

  2. 可以成为左值引用(T&),但无法从左值引用转到左值T

#include <iostream>

class Base {
public:
	Base() = default;

	Base(Base&& other) = delete;
};

void func(Base rd1) {

}

int main() {
	Base b1;
	Base& b2 = b1;

	Base b3 = b1; //无法引用 函数 "Base::Base(const Base &)" (已隐式声明) -- 它是已删除的函数
	Base b4 = b2; //无法引用 函数 "Base::Base(const Base &)" (已隐式声明) -- 它是已删除的函数

	func(b1); //无法引用 函数 "Base::Base(const Base &)" (已隐式声明) -- 它是已删除的函数



    //不存在用户定义的从 "std::reference_wrapper<Base>" 到 "Base" 的适当转换
	func(std::ref(b1)); //由于没有拷贝构造,也无法从Base&转换成Base,此处也会报错
}

上面这样写依然报错,改写func:

template<class _fn>
void func1(_fn rd1) { //泛型
	auto aa = rd1();
}

void func2(Base& rd1) { //明确要求接收左值引用
	auto aa = rd1();
}

int main() {
	Base b1;

	func1(std::ref(b1));

	func2(std::ref(b1)); //std::reference_wrapper<Base>可以直接转Base&
	func2(b1); //Base可以传到Base&
}

泛型本身支持左值或左值引用,但此处的Base不支持拷贝,所以调用func1只能用std::ref


评论