如何正确消除继承的 typedef 的歧义?以及如何缓解他们的创作?
How to correctly disambiguate inherited typedefs? And how to ease their creation?
让我们考虑一下我创建 Typedef
class 以自动继承别名的代码。
#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();
};
通常这没有问题,但是当我继承多个 classes 时,我必须消除多个继承别名之间的歧义。
有没有更简单的方法来消除歧义?(可能具有 C++14/17 特性)
如果没有,有没有更简单的方法自动为每个class创建别名?我不想在每个 class 定义中 typedef std::unique_ptr<Foo> Ptr
。 我希望在每个 class 中公开显示 Foo::Ptr
、Foo::ConstPtr
。
最新的 Eclipse Oxygen 解析器坏了吗? 它通常能正确理解代码(包括 A),但突出显示 (B) 有错误:"typedef is ambiguous" .在这种情况下,原因似乎是多重继承。 GCC 没有问题,编译没有任何警告。
如果我的 Typedef
class 声明了更多别名,并且我有冲突 - 有没有比 [=16= 更简单的方法来解决所有冲突], ...::ConstPtr
全部?
如果您真的坚持这种行为,一种可能是添加额外的 classes...
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> { ... };
这样,每个 class 都有一种简单的方法来提供自己的别名,即使是多重继承也是如此。
但是,正如我在评论中所解释的那样,我通常不建议采用这种方法。
应避免多重 (public) 继承,因为它会产生强耦合。通常最好改用组合。 interface classes 是一个例外(只有纯虚函数,如果您打算能够从其接口指针销毁对象,则可能是虚析构函数)。混合可能是多重继承可能有用的另一种情况,但在这种情况下,您将使用私有继承,即使这样组合也可能更可取。耦合越少,如果您想进行重大更改,系统维护起来就越容易。
另外,正如我在评论中所解释的那样,定义此类 typedef 可能不是一个好主意,因为 std::unique_ptr<>
具有与之关联的行为,并且出于文档目的,您编写 std::unique_ptr<A> Func();
可能会更好反正。它使函数的使用方式更加明显。
让我们考虑一下我创建 Typedef
class 以自动继承别名的代码。
#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();
};
通常这没有问题,但是当我继承多个 classes 时,我必须消除多个继承别名之间的歧义。
有没有更简单的方法来消除歧义?(可能具有 C++14/17 特性)
如果没有,有没有更简单的方法自动为每个class创建别名?我不想在每个 class 定义中
typedef std::unique_ptr<Foo> Ptr
。 我希望在每个 class 中公开显示Foo::Ptr
、Foo::ConstPtr
。最新的 Eclipse Oxygen 解析器坏了吗? 它通常能正确理解代码(包括 A),但突出显示 (B) 有错误:"typedef is ambiguous" .在这种情况下,原因似乎是多重继承。 GCC 没有问题,编译没有任何警告。
如果我的
Typedef
class 声明了更多别名,并且我有冲突 - 有没有比 [=16= 更简单的方法来解决所有冲突],...::ConstPtr
全部?
如果您真的坚持这种行为,一种可能是添加额外的 classes...
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> { ... };
这样,每个 class 都有一种简单的方法来提供自己的别名,即使是多重继承也是如此。
但是,正如我在评论中所解释的那样,我通常不建议采用这种方法。
应避免多重 (public) 继承,因为它会产生强耦合。通常最好改用组合。 interface classes 是一个例外(只有纯虚函数,如果您打算能够从其接口指针销毁对象,则可能是虚析构函数)。混合可能是多重继承可能有用的另一种情况,但在这种情况下,您将使用私有继承,即使这样组合也可能更可取。耦合越少,如果您想进行重大更改,系统维护起来就越容易。
另外,正如我在评论中所解释的那样,定义此类 typedef 可能不是一个好主意,因为 std::unique_ptr<>
具有与之关联的行为,并且出于文档目的,您编写 std::unique_ptr<A> Func();
可能会更好反正。它使函数的使用方式更加明显。