PIMPL习语无障碍问题
PIMPL idiom accessibility issue
我已经实现了我的 class,比方说 class A
使用标准的 PIMPL 习惯用法。
当我尝试为我的实现重载 <<
运算符时出现问题 class 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
class,在 A
.
中声明为私有
现在我对如何解决这个问题感到进退两难。一种方法是也声明 class A
的重载运算符友元。另一种方法是私有声明 class AImpl
public.
哪种方法更好更安全?
恕我直言,您滥用了 PIMPL 习语。这个习语要求实现是真正私有的,即 AImpl
不应该在头文件中定义(供所有人查看),而应该在 A.cpp
中定义,其中 <<
运算符属于。
如果你这样做,<<
运算符在头文件中声明也是毫无意义的,你访问 PIMPL 的唯一方法就是通过包含 class 的方法。您可以改为定义 ostream &operator <<(ostream &os, const A &obj)
并将其设为 A
的 friend
。
请注意,使用这种方法,AImpl
不需要限制访问。无论如何,它的字段和大小只能从 A.cpp
获得。但是,如果你想让 AImpl
的内部结构成为 private
,你也可以使 ostream &operator <<(ostream &os, const A &obj)
成为 AImpl
的 fried
。
/* 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;
...
}
我已经实现了我的 class,比方说 class A
使用标准的 PIMPL 习惯用法。
当我尝试为我的实现重载 <<
运算符时出现问题 class 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
class,在 A
.
中声明为私有
现在我对如何解决这个问题感到进退两难。一种方法是也声明 class A
的重载运算符友元。另一种方法是私有声明 class AImpl
public.
哪种方法更好更安全?
恕我直言,您滥用了 PIMPL 习语。这个习语要求实现是真正私有的,即 AImpl
不应该在头文件中定义(供所有人查看),而应该在 A.cpp
中定义,其中 <<
运算符属于。
如果你这样做,<<
运算符在头文件中声明也是毫无意义的,你访问 PIMPL 的唯一方法就是通过包含 class 的方法。您可以改为定义 ostream &operator <<(ostream &os, const A &obj)
并将其设为 A
的 friend
。
请注意,使用这种方法,AImpl
不需要限制访问。无论如何,它的字段和大小只能从 A.cpp
获得。但是,如果你想让 AImpl
的内部结构成为 private
,你也可以使 ostream &operator <<(ostream &os, const A &obj)
成为 AImpl
的 fried
。
/* 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;
...
}