如何正确消除继承的typedef的歧义?以及如何缓解他们的创作?

时间:2017-07-29 12:12:32

标签: c++ templates typedef multiple-inheritance

让我们考虑这样的代码,我创建了Typedef类来自动继承别名。

#include <memory>

template <typename T>
struct Typedef
{
    typedef std::unique_ptr<T> Ptr;
    typedef std::unique_ptr<const T> ConstPtr;
};

struct X : public Typedef<X> { Ptr Func(); }; // no problem, Ptr = std::unique_ptr<X>
struct Y : public Typedef<Y> { Ptr Func(); }; // no problem, Ptr = std::unique_ptr<Y>

struct A : public X, public Typedef<A>
{
    using Typedef<A>::Ptr; // (A), better than typedef typename Typedef<A>::Ptr Ptr, am I right?
    Ptr Func();
};

struct B : public X, public Y, public Typedef<B>
{
    using Typedef<B>::Ptr; // (B)
    Ptr Func();
};

通常这没有问题,但是当我从多个类继承时,我必须消除多个继承别名的歧义。

  1. 有没有更简单的消除歧义的方法?(可能使用C ++ 14/17功能)

  2. 如果没有,是否有更简单的方法为每个类自动创建别名?我不想在每个班级定义中typedef std::unique_ptr<Foo> Ptr我希望在每个班级中公开显示Foo::PtrFoo::ConstPtr

  3. 最新的Eclipse Oxygen解析器是否已损坏?它通常正确理解代码(包括A),但突出显示(B)错误:&#34; typedef不明确&#34;。在这种情况下,似乎原因是多重继承。海湾合作委员会没有任何问题,编制时没有任何警告。

  4. 如果我的Typedef类声明了更多别名,而且我有冲突 - 是否有更简单的方法来解决所有冲突而不是using Typedef<Foo>::Ptr...::ConstPtr这些冲突?

1 个答案:

答案 0 :(得分:1)

如果你真的坚持这种行为,一种可能性是增加额外的类......

struct XBase { ... };
struct YBase { ... };

struct X : public XBase, public Typedef<X> { ... };
struct Y : public YBase, public Typedef<Y> { ... };

struct ABase { ... };
struct BBase { ... };

struct A : 
    public ABase, 
    public XBase, 
    public Typedef<A> { ... };

struct B : 
    public BBase, 
    public XBase, 
    public YBase, 
    public Typedef<B> { ... };

这样,每个类都有一种简单的方法来提供自己的别名,即使有多重继承。

但是,正如我的评论中所解释的那样,我一般不建议采用这种方法。

应该避免多个(公共)继承,因为它会创建强耦合。通常更好的是使用组合物。接口类是一个例外(如果您打算能够从其接口指针中销毁对象,则只有纯虚函数,可能还有虚拟析构函数)。混合可能是多重继承可能有用的另一种情况,但在这种情况下,您将使用私有继承,即使这样,组合可能更可取。如果您想要进行重大更改,那么您的耦合越少,系统就越容易维护。

同样如我的评论中所解释的那样,定义这样的typedef可能不是一个好主意,因为std::unique_ptr<>具有与之关联的行为,并且无论如何,为了文档目的,您可能更好地编写std::unique_ptr<A> Func();。它使得如何使用该函数变得更加明显。