下面的代码出乎意料地有效!
class CameraBuffer;
class CameraBufferAccessor{
friend CameraBuffer;
private:
CameraBufferAccessor(const int &data, const int &mutex);
public:
CameraBufferAccessor() = default;
CameraBufferAccessor(const CameraBufferAccessor &) = delete;
CameraBufferAccessor(CameraBufferAccessor &&) = delete;
void operator=(const CameraBufferAccessor &other) = delete;
void operator=(CameraBufferAccessor &&other) = delete;
};
class CameraBuffer {
public:
const CameraBufferAccessor getReadAccess() const {
return {1, 2};
}
};
int main() {
auto buffer = CameraBuffer();
CameraBufferAccessor a = buffer.getReadAccess();
CameraBufferAccessor b = a;
这里
CameraBufferAccessor b = a;
正如预期的那样抛出错误,因为复制构造函数被显式删除。
但是发生了一些我没有预料到的事情,我一直在寻找它,到目前为止还没有解释。 尽管
CameraBufferAccessor a = buffer.getReadAccess();
行使用了一个函数,但它仍然可以工作
具有非引用返回,其本身应该使用复制构造函数,其次返回的 CameraBufferAccessor
应复制到 a
再次使用复制/移动构造函数初始化 a
,但它会编译并且不会抛出.
我听说出于优化目的的编译器可以在必要时绕过复制构造, 如果是这种情况,我该如何判断编译器何时这样做?
我以为是因为
getReadAccess
的返回语句中的大括号直接初始化了返回值,所以我尝试了return CameraBufferAccessor(1, 2)
;但它仍然有效。也许编译器优化?
这是一个非常棘手的问题,但我想我有答案。
您不希望用户初始化
CameraBufferAccessor
,因此您创建了私有构造函数、默认构造函数和复制构造函数。为了进行测试,您删除了除私有构造函数之外的所有构造函数:CameraBufferAccessor(const int &data, const int &mutex);
。因此,当您尝试使用 CameraBufferAccessor a = buffer.getReadAccess();
进行初始化时,您将其传递给朋友静态类,并且静态方法可以访问私有构造函数:
class CameraBuffer {
public:
const CameraBufferAccessor getReadAccess() const {
return {1, 2};
}
};
在这里加好友:
class CameraBufferAccessor{
friend CameraBuffer;
//...
我希望我能帮助您更好地理解为什么可以访问构造函数。