【问题标题】:C++: How to prevent private names from polluting derived types?C++:如何防止私有名称污染派生类型?
【发布时间】: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 类。这是否意味着你不能在你的新类中使用任何新的(甚至是私有的)名称而不破坏其他人的代码?

这里的约定是什么?

【问题讨论】:

标签: c++ inheritance private base ambiguity


【解决方案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;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-09
        • 1970-01-01
        • 2020-03-13
        • 1970-01-01
        • 2016-01-17
        相关资源
        最近更新 更多