C++:如何防止私有名称污染派生类型?
Posted
技术标签:
【中文标题】C++:如何防止私有名称污染派生类型?【英文标题】:C++: How to prevent private names from polluting derived types? 【发布时间】:2020-08-22 08:45:36 【问题描述】:今天让我震惊的是,这段代码 sn-p 有一个模棱两可的名称引用:
class A
private:
typedef int Type;
;
class B
public:
typedef int Type;
;
class D : A, B
Type value;//error: reference to 'Type' is ambiguous
;
嗯!想象一下,您是 A
类的作者,并且您的类已经被不同的人和不同的项目到处使用。有一天你决定重写你的A
类。这是否意味着你不能在你的新类中使用任何新的(甚至是私有的)名称而不破坏其他人的代码?
这里的约定是什么?
【问题讨论】:
类似问题:***.com/q/5445299/1025391 , ***.com/q/37206557/1025391 pimpl 成语,让你不再需要更改私有接口。 C++ 程序的语义不受public/private
声明的影响。但他们的合法性是。如果它是第一次编译,将private
更改为public
应该不会破坏它。
【参考方案1】:
是的,你是对的。如果您决定稍后进行更改,使用当前的格式/逻辑/编码风格可能会破坏其他人的代码。 尝试使用 PIMPL 或完全限定符号。 你的例子是一个很好的例子,为什么不使用完全限定符号不是一个好主意。 像这样的代码也是同样的问题:
using namespace std;
上面的代码行可能会破坏很多东西。
【讨论】:
【参考方案2】:正如@Jarod42 提到的,它需要遵循pimpl idiom(指向实现的指针)来分离接口和实现:
啊.h
#include <memory>
class A
public:
A();
~A();
private:
class AImpl;
std::unique_ptr<AImpl> pimpl;
;
A.cpp
#include "A.h"
class A::AImpl
private:
typedef int Type;
/* .. */
;
A::A(): pimpl(new AImpl)
A::~A() = default;
main.cpp
#include "A.h"
class B
public:
typedef int Type;
;
class D : A, B
Type value;
;
【讨论】:
【参考方案3】:我认为这里没有问题,这不是因为符号不存在是私有的。如果您尝试访问私有成员,编译器会告诉您无法访问它,而不是它不存在。
另外,我会说使用多重继承而不是完全限定符号是一种不好的做法。
class D : A, B
B::Type value;
;
【讨论】:
以上是关于C++:如何防止私有名称污染派生类型?的主要内容,如果未能解决你的问题,请参考以下文章