【发布时间】:2021-06-11 22:40:57
【问题描述】:
我正在尝试使用类来抽象原始句柄的显式创建和销毁。实际句柄存储为私有类成员(这样用户就不会与较低级别的细节交互),它在构造时创建并在销毁时销毁。是否有某种设计模式可以帮助实现下面的代码试图实现的目标?
请注意,可能存在大量相互依赖的类,因此用大量友元语句污染每个类既乏味又不好。
#include <memory>
// Handle types may vary
typedef uint32_t A_Handle;
typedef uint32_t B_Handle;
typedef int64_t C_Handle;
extern void createA(A_Handle*);
extern void destroyA(A_Handle);
extern void createB(B_Handle*);
extern void destroyB(B_Handle);
extern void createC(C_Handle*, A_Handle, B_Handle);
extern void destroyC(C_Handle, A_Handle, B_Handle);
class A
{
private:
A_Handle handle_;
public:
A()
{
createA(&handle_);
}
~A()
{
destroyA(handle_);
}
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B
{
private:
B_Handle handle_;
public:
B()
{
createB(&handle_);
}
~B()
{
destroyB(handle_);
}
B(const B&) = delete;
B& operator=(const B&) = delete;
};
class C
{
private:
C_Handle handle_;
public:
std::shared_ptr<A> a;
std::shared_ptr<B> b;
C(const std::shared_ptr<A>& a, const std::shared_ptr<B>& b)
: a(a)
, b(b)
{
// Error a->handle_ and b->handle_ is private
createC(&handle_, a->handle_, b->handle_);
}
~C()
{
// Error a->handle_ and b->handle_ is private
destroyC(handle_, a->handle_, b->handle_);
}
C(const C&) = delete;
C& operator=(const C&) = delete;
};
// ...
int main()
{
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();
std::shared_ptr<C> c = std::make_shared<C>(a, b);
// ...
return EXIT_SUCCESS;
}
【问题讨论】:
-
推荐观察
A和B类中的Rule of Three (or five)。 -
大量的“
extern”是否支持C接口? -
@user4581301 或零规则。由于这个类处理所有权,我们至少删除了不需要的成员(看起来这些类不应该是可复制的)
-
@user4581301 是的,你说得对,类应该是不可复制的(我已经用删除的复制构造函数和赋值运算符更新了代码)。但我不明白零规则是如何工作的,因为句柄永远不会被破坏,因为没有析构函数。
-
零规则不适用于编写的类,但是一旦我有一个需要由多个类使用的特殊处理的资源,我将把该资源包装在一个完全符合 RAII 的类中
A、B和C类将使用该类来遵守零规则。让观察 3 和 5 的班级尽可能靠近他们保护的资源,以便其他班级尽可能愚蠢。
标签: c++ oop design-patterns friend handle