C++ C++;派生类上的模板转换
我有3个相互派生的类: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;
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
的单个实例向上强制转换您不能像这样直接强制转换组。你需要做的是
不能将一种类型的容器强制转换为另一种类型的容器。在这种情况下,组基本上是一个容器
您需要逐个复制元素。不,这三种类型是不相关的,您不能在它们之间强制转换 理解原因的一个很好的例子是:假设您有一个
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的工厂是工厂和工厂(在某种意义上)以及工厂的类型,因为它将创建所需类型的对象可能,您需要传递这些组的迭代器,而不是团体本身。在这种情况下,不需要铸造