类型提供基类(或不可复制)和虚继承

时间:2016-09-26 13:31:33

标签: c++ c++11

我过去使用的基类纯粹是为了使类型信息保持不变(类似于traits类,以及ios_base)。这些类通常没有数据,但只提供常用的类型(可能是装饰原始类型),这个想法是在发生变化时,在一个位置改变类型常量。我一直在想,对于可能从这些类型类继承的接口使用虚拟继承是否有任何优势。类似情况的一个众所周知的例子是可以派生boost :: noncopyable的接口(不是我经常使用boost :: noncopyable作为接口)。

以下是有关案例的一个小例子:

#include <iostream>
#include <memory>


struct Path{};

struct SomeTypeDefs //Or something providing services similar boost::noncopyable
{
    typedef std::shared_ptr<Path> PathPtr;
};


struct InterfaceX : SomeTypeDefs
{
    virtual PathPtr getPathX() const = 0;
};

struct InterfaceY : SomeTypeDefs
{
    virtual PathPtr getPathY() const = 0;
};

struct Impl : InterfaceX, InterfaceY
{
    private:
      PathPtr getPathY() const override{ return PathPtr{}; }
      PathPtr getPathX() const override{ return PathPtr{}; }
};

void foo(const InterfaceX&)
{
    std::cout << "foo X" << std::endl;
}
void foo(const InterfaceY&)
{
    std::cout << "foo Y" << std::endl;
}

int main() 
{
    Impl impl;
    foo(static_cast<InterfaceX&>(impl));
    foo(static_cast<InterfaceY&>(impl));
    return 0;
}

在这种情况下,我看不到使用虚拟继承的好处(有没有)?

1 个答案:

答案 0 :(得分:1)

警告:意见,可能不会直接回答这个问题..

坦率地说,这种情况可以通过策略类而不是继承来更好地处理!

例如,我会

struct SomeTraits {
  typedef std::shared_ptr<Path> PathPtr;
};

// here class is hard-wired to policy
struct InterfaceX
{
    virtual SomeTraits::PathPtr getPathX() const = 0;
};

struct InterfaceY
{
    virtual SomeTraits::PathPtr getPathY() const = 0;
};

然后你可以这样做:

// here class doesn't really care about specific policy...
template <typename Traits>
struct InterfaceX
{
    typedef typename Traits:: PathPtr;
    virtual PathPtr getPathX() const = 0;
};

template <typename Traits>
struct InterfaceY
{
    typedef typename Traits:: PathPtr;
    virtual Traits getPathY() const = 0;
};

这为您提供了很多可能性(请参阅基于策略的设计..)我认为坦率地说比继承更清晰,特别是如果您要定义类型