C++ C++;派生类上的模板转换

C++ C++;派生类上的模板转换,c++,C++,我有3个相互派生的类: class Basic{ ... } class Extended : public Basic{ ... } class Full : public Extended{ ... } 我有一个模板类,其中包含5-5个此类: template <class T> class group{ public: ... private: T one, two, three, four, five;

我有3个相互派生的类:

class Basic{
...
}

class Extended : public Basic{
...
}

class Full : public Extended{
...
}
我有一个模板类,其中包含5-5个此类:

template <class T>
    class group{
    public:
             ...
    private:
        T one, two, three, four, five;
    };

group<Basic> basicGroup;
group<Extended> extendedGroup;
group<Full> fullGroup;
模板
班级{
公众:
...
私人:
T一,二,三,四,五;
};
基本组;
组扩展组;
全组;

例如,我可以轻松地将fullGroup转换为basicGroup,或将extendedGroup转换为basicGroup吗?(我只想向上)

< p>一个具有不同参数的类模板被C++类型的系统视为完全不同的类型。因此,
的类型不同,您无法在这两种类型之间安全地进行强制转换


您只能对
Full
Extended
的单个实例向上强制转换您不能像这样直接强制转换组。你需要做的是

  • 做一个泛型组类,其中一个5是指向Basic的指针
  • 使FullGroup派生自ExtendedGroup,后者将派生自basicGroup

  • 不能将一种类型的容器强制转换为另一种类型的容器。在这种情况下,组基本上是一个容器


    您需要逐个复制元素。

    不,这三种类型是不相关的,您不能在它们之间强制转换

    理解原因的一个很好的例子是:假设您有一个
    std::list
    ,其中
    Dog
    继承自
    Animal
    。您可能会认为,<>代码> STD::List<<代码>可以被转换成<代码> STD::列表;但是这个代码会发生什么呢

    std::list<Dog> dogList;
    // ... fill dogList as appropriate
    std::list<Animal> animalList = dogList; // Should this be legal?
    Animal aml = animalList.get(); // Fine; you get a Dog, which is an Animal
    animalList.insert(Cat()); // Aww: you are trying to add a Cat to a Dog list!
    
    std::list dogList;
    // ... 根据需要填写狗名单
    std::list animalList=dogList;//这是否合法?
    动物aml=animalList.get();//好的你有一只狗,它是一种动物
    animalList.insert(Cat());//Aww:你想把一只猫加到狗的名单上!
    
    解决方案是创建一种视图类,它可以包装一个组,并将单个对象公开为基类实例:

    template <class T>
    class group{
    public:
        const T & getOne() { return one; }
    private:
        T one, two, three, four, five;
    };
    
    template <class T, U>
    class group_view {
    public:
        group_view(group<T> & inner) : innerGroup(inner) {}
    
        const U & getOne() { return dynamic_cast< const U &>(one); }
    private:
        group<T> & innerGroup;
    };
    
    模板
    班级{
    公众:
    const T&getOne(){return one;}
    私人:
    T一,二,三,四,五;
    };
    模板
    类组视图{
    公众:
    组视图(组和内部):内部组(内部){}
    const U&getOne(){return dynamic_cast(one);}
    私人:
    组&内组;
    };
    
    您可以这样使用它:

    group<Full> fullGroup;
    group_view<Full, Extended> extendedGroupView(fullGroup);
    
    全组;
    组视图扩展组视图(完整组);
    

    如果将
    group
    的公共接口提取到抽象基类中,甚至可以多态地使用
    group\u视图

    大多数时候,你不想动态施法,也不在乎你下面是什么类型。有一个操作要在基类上以多态方式执行,只需调用它


    但是请注意,您的组模板包含类的实例,而不是指向它们的指针/共享指针。因此,如果不对较小类的组进行切片,则无法将完整或扩展类添加到该组。

    是和否,类型系统在这方面仍然存在缺陷,因为在完美的OO中,您将拥有一个ReadOnlyList,其中将派生一个ReadOnlyList。当然,这个列表必须在可写的地方创建,而RealOnLyList可能没有数据的“所有权”,但有时候这些数据是无关的,特别是在层次结构中。这是不是说,我不能说这个机制不能被改进,但是目前C++是这样工作的,这就是原因。C#4.0中引入的in-out机制是一个很好的改进,您可以为每个模板参数指定协方差或逆变。但它在C++中不起作用。请注意,我的RealDyLy列表不一定是一个集合,它只需要是读取集合的某种方式。所以它可能是常量迭代器范围。我发现协方差问题更像是工厂模型中的一个问题,在上面的模型中,在axample中创建Full的工厂是工厂和工厂(在某种意义上)以及工厂的类型,因为它将创建所需类型的对象可能,您需要传递这些组的迭代器,而不是团体本身。在这种情况下,不需要铸造