首页 > 解决方案 > C++ Template-based Design - 构建基于模板的项目时,最好的模板指南是什么?(就有效的铸造类型而言)

问题描述

假设模板化 C++ 代码的结构如下:

class SpokenLang
{
    private: std::string lang;
    ...
};

class Greek : public SpokenLang
{
    ...
};
class English : public SpokenLang
{
    ...
};

// HDT (stands for Height Data Type and is the data type used to specify the selected HT)
template <typename HDT> // For example we could use either float or double for the Height Data Type
class AbsoluteHeight
{
    private: HDT height;
    ...
};


// HDT (stands for Height Data Type and is the data type used to specify the selected HT)
template <typename HDT> // For example we could use either float or double for the Height Data Type
class RelativeHeight
{
    private: HDT height;
    ...
};

// SL (stands for SpokenLanguage derived classes
// HT (stands for Height Type - either AbsoluteHeight or RelativeHeight)
// HDT (stands for Height Data Type and is the data type used to specify the selected HT)
template <typename SL, typename HT, typename HDT>
class Student
{
    private: SL spokenLanguage;
             HT<HDT> height;
    ...
}

现在假设您有一个学生数组。什么是最好的模板设计,以促进简单明了的设计,而不必指定用于每个学生对象的确切类型?

例如:我应该在运行时使用指针并静态转换它们以猜测每个学生使用的适当类型吗?

Student** students = new Student*[10];
students[0] = new Student<Greek,AbsoluteHeight,float>();
students[1] = new Student<English,RelativeHeight,float>();
...

或者使用以下更紧凑的设计(在模板参数使用的数量方面更紧凑?

// ...(declarations omitted for brevity)...

// SL (stands for SpokenLanguage derived classes
// HT (stands for Height Type - for example AbsoluteHeight<float> or RelativeHeight<double>)
template <typename SL, typename HT>
class Student
{
    private: SL spokenLanguage;
             HT height;
    ...
};
...
Student** students = new Student*[10];
students[0] = new Student<Greek,AbsoluteHeight<float>>();
students[1] = new Student<English,RelativeHeight<double>>();
...

当我需要操作学生对象时,如何安全地投射有关嵌套模板参数的“缺失”信息?我的问题是:

注意:我不想使用任何糖 STL 解决方案,如 is_base 等。我想要纯 C++ 解决方案。好像根本没有 STL 库。(我来自专业的 C 和专业的 Java 背景)。

标签: c++templatesdesign-patternstypescasting

解决方案


在开始模板之前,您应该考虑一个清晰的界面!

有一个类层次结构,里面有或多或少完全不同的数据类型,没有公共接口,这有什么意义?

在您必须手动铸造某些东西时,您会清楚地表明您的设计已损坏。信息必须在类内部,而不是在访问对象之前需要转换的代码中。如果您清理了界面,我相信您不需要任何演员表!

在上面的示例中,它似乎是定义接口的起点,该接口使您的数据可以访问代码的其他部分,例如:

template <typename SL, typename HT, typename HDT>
class Student: public StudentInterface {...};

现在您必须定义访问数据所需的界面类型,例如打印、编辑、...

如果您现在喜欢编译时多态性或运行时多态性,则取决于您。当您使用许多可能的模板变体定义一组非常复杂的数据时,我希望运行时多态性更容易实现并且对于您的用例也足够了。


推荐阅读