简体   繁体   English

PIMPL习惯用法可访问性问题

[英]PIMPL idiom accessibility issue

I've implemented my class, lets say class A using standard PIMPL idiom. 我已经实现了我的课程,可以使用标准的PIMPL习惯用法来说A类。
Problem arises when i try overloading << operator for my implementation class AImpl 当我尝试为实现类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) {
     ...
}

Problem stems from overloaded operator not having access to AImpl class, declared private in A . 问题源于无法在A声明为private的AImpl类的重载运算符。
Now i'm in sort of a dilemma over how i should resolve this. 现在,我在如何解决此问题上处于两难境地。 One way is declaring overloaded operator friend of class A too. 一种方法也是声明A类的重载运算符。 The other way is making private declaration of class AImpl public. 另一种方法是将AImpl类的私有声明公开。

Which approach is better and safer? 哪种方法更好,更安全?

IMHO you're misusing the PIMPL idiom. 恕我直言,您滥用PIMPL习惯用语。 The idiom calls for the implementation to be really private, that is AImpl should not be defined in a header file (for everyone to see), rather it should probably be defined in A.cpp where also the << operator belongs. 这个习惯用法要求实现是真正私有的,也就是说, AImpl不应该在头文件中定义(每个人都可以看到),而应该在A.cpp中定义, <<运算符也应属于此。

If you do that the << operator is pointless to declare in header file as well, the only way you would access the PIMPL would be via the containing class anyway. 如果这样做<<运算符也没有必要在头文件中声明,那么访问PIMPL的唯一方法就是通过包含类。 You would define ostream &operator <<(ostream &os, const A &obj) instead and make that a friend of A . 您应改为定义ostream &operator <<(ostream &os, const A &obj)并使其成为Afriend

Note that with this approach the AImpl does not need to be as restrictive about access. 注意,使用这种方法, AImpl不必对访问进行限制。 It's field and size would only be available from A.cpp anyway. 无论如何,它的字段和大小只能从A.cpp But if you want to make the internals of AImpl be private you could make ostream &operator <<(ostream &os, const A &obj) a fried of AImpl as well. 但是,如果你想的内部AImplprivate ,你可以做ostream &operator <<(ostream &os, const A &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;
     ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM