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;

ma​​in.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++:如何防止私有名称污染派生类型?的主要内容,如果未能解决你的问题,请参考以下文章

C++多继承

C ++:如何在派生类中定义基类构造函数,如果基构造函数具有带有私有成员的初始化列表[重复]

C++ 设计模式:可能有继承的方法私有到派生类?

详解C++中基类与派生类的转换以及虚基类

C++ 派生类访问属性

C++继承:公有,私有,保护