【问题标题】:PIMPL idiom accessibility issuePIMPL 成语可访问性问题
【发布时间】:2015-10-29 04:17:24
【问题描述】:

我已经实现了我的课程,比如说A 使用标准 PIMPL 成语。
当我尝试为我的实现类 AImpl 重载 << 运算符时出现问题

/* A.h */
class A {
public:
     ...
private:
     class AImpl;
     AImpl *impl;
}
/* Aimpl.h */
class AImpl {
     ...
     friend ostream &operator <<(ostream &os, const AImpl &impl);
     ...
}
/* elsewhere.cpp */
ostream &operator <<(ostream &os, const AImpl &impl) {
     ...
}

问题源于重载运算符无法访问 AImpl 类,在 A 中声明为私有。
现在我对如何解决这个问题有点进退两难。一种方法是声明A 类的重载运算符朋友。另一种方法是对 AImpl public 类进行私有声明。

哪种方法更好更安全?

【问题讨论】:

  • 是的,另一种方法是在AImpl 中定义operator&lt;&lt;,而不是仅仅声明它。通常情况下,使用 pImpl 时,“Impl”类最好放在“A.cpp”中,将声明和定义分开并没有什么好处,而且相当冗长。
  • 这是用于序列化还是打印?通常,您不想打印班级的私人部分,因此您只需要一个运算符
  • 除了 {{A.cpp}} 之外,您如何/为什么可以访问 {{AImpl}}?

标签: c++ access-modifiers pimpl-idiom


【解决方案1】:

恕我直言,您误用了 PIMPL 成语。习惯用法要求实现是真正私有的,即 AImpl 不应定义在头文件中(供所有人查看),而应该在 A.cpp 中定义 &lt;&lt; 运算符所属的位置。

如果你这样做,&lt;&lt; 运算符在头文件中声明也毫无意义,那么访问 PIMPL 的唯一方法就是通过包含类。您将改为定义 ostream &amp;operator &lt;&lt;(ostream &amp;os, const A &amp;obj) 并将其设为 friendA

请注意,通过这种方法,AImpl 不需要限制访问。无论如何,它的字段和大小只能从A.cpp 获得。但如果你想让AImpl 的内部结构为private,你也可以将ostream &amp;operator &lt;&lt;(ostream &amp;os, const A &amp;obj) 设置为friedAImpl

/* A.h */
class A {
public:
     ...
private:
     class AImpl;
     AImpl *impl;

     friend ostream &operator <<(ostream &os, const A &obj);
}

/* A.cpp */
class AImpl {
public:
     // OR:
     friend ostream &operator <<(ostream &os, const A &obj);

     ...
}

ostream &operator <<(ostream &os, const A &obj) {
     AImpl* impl = obj.impl;
     ...
}

【讨论】:

  • 我很抱歉,因为没有足够清楚地表达我的问题。我想为AAImpl 重载&lt;&lt; 运算符,因此我可以使用AImpl 的运算符为A 定义运算符。此外,我忽略了提到 AImpl.h 是私有标头而不是公共标头,所以我不认为我在滥用 PIMPL。但是,最好的解决方案似乎是仅重载主类的运算符,这是我在发布此问题后大约 10 分钟发现的。这似乎也是您的解决方案。
  • @Kijan 您仍然可以这样做,但由于AImpl.h 是私有的(仅供A.cpp 使用),因此头文件的内容宁愿属于A.cpp)。 AImpl 的操作符可能不需要访问 A:通常 pipml 没有对包含对象的任何引用,因此没有 A 对象希望 AImpl::operator&lt;&lt; 对其进行操作。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多