gpt4 book ai didi

c++ - 如何仅将实现公开给 pimpl 习语中的一组指定类?

转载 作者:太空狗 更新时间:2023-10-29 21:00:13 24 4
gpt4 key购买 nike

让我们有一个class A它有一个内部 class A::Impl . class AllowedToAccess应该能够得到 A::Impl&来自 class A ,没有其他类(class)应该能够做到这一点,甚至不知道 class A::Impl存在。

class A_1
{
public:
class Impl;

Impl& impl();
const Impl& impl() const;

private:
std::unique_ptr<Impl> m_impl;
};

class A_2
{
private:
friend class AllowedToAccess;

class Impl;
std::unique_ptr<Impl> m_impl;
};

class A_3
{
private:
friend class AllowedToAccess;

class Impl;

class ImplContainer
{
friend class A_3;
std::unique_ptr<Impl> impl;
} m_implContainer;

Impl& impl(); // return *m_implContainer.impl;
const Impl& impl() const; // return *m_implContainer.impl;
};

下面是一些代码来说明我的想法。

A_1

优点:m_impl是安全的。

缺点:类不应该知道 A::Impl会知道它(虽然他们不知道 A::Impl 到底是什么)。

A_2

优点:类不应该知道 A::Impl不会知道的。

缺点:m_impl不安全( AllowedToAccess 可能只是将其设置为 nullptr )。

A_3

优点:类不应该知道 A::Impl不会知道它和m_impl是安全的。

缺点:ImplContainer 的样板代码.

有什么更好的主意吗?

编辑:提出了这样的解决方案。

template <typename T>
class Accessor
{
private:
friend class AllowedToAccess;

typedef typename T::Impl impl_t;

static typename T::Impl& impl(T& t)
{
return *t.m_impl;
}

static const typename T::Impl& impl(const T& t)
{
return *t.m_impl;
}
};

class A
{
private:
friend class Accessor<A>;

class Impl;
std::unique_ptr<Impl> m_impl;
};

class A::Impl
{
public:
void f() const
{

}
};

class AllowedToAccess
{
public:
AllowedToAccess()
{
const A a;

const Accessor<A>::impl_t& impl = Accessor<A>::impl(a);

impl.f();
}
};

有一个代码实现层,所有这些类都将作为 friend 添加到 Accessor。

并且为了进一步隐藏访问器只会被前向声明为 template <typename T> class Accessor; 的东西在公共(public)代码中。并在私有(private)代码中定义。

最佳答案

如果可以将与 m_impl 本身一起工作的所有逻辑移动到基类,则可以使派生类无法访问 m_impl,但允许它获得对 Impl 的引用,然后使 Access 类成为派生类的友元:

class Base {
protected:
class Impl;
Impl& impl();
private:
std::unique_ptr<Impl> m_impl;
};

class Base::Impl {
public:
Impl() {}
};

Base::Impl& Base::impl() { return *m_impl; }

class Derived : private Base {
public:
friend class Access;
Derived() {
auto& ptr = impl(); // ok
auto& ptr1 = m_impl; // error
}
};

class Access {
public:
Access(Derived& d) {
auto& ptr = d.impl(); // ok
auto& ptr1 = d.m_impl; // error
}
};

关于c++ - 如何仅将实现公开给 pimpl 习语中的一组指定类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22611210/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com