【发布时间】:2021-04-02 11:21:12
【问题描述】:
使用虚函数时,对基类和所有派生类都使用单个类模板通常很方便。我的问题是:C++ 编译器以这种方式定义的类与没有模板定义的相同类有什么不同吗?
以下是使用模板创建的一些类的示例:
template <typename T=void> struct Adder;
template <> struct Adder <void>
{
virtual double add(double a, double b)
{
return (a+b);
}
};
template <typename T> struct Adder : Adder <void>
{
virtual double add(double a, double b)
{
return ((T)a+(T)b);
}
};
using AdderBase = Adder <void>;
using AdderInt = Adder <int>;
using AdderFloat = Adder <float>;
using AdderDouble = Adder <double>;
int main(int argc, char* argv[])
{
AdderBase* addI = new AdderInt;
AdderBase* addF = new AdderFloat;
AdderBase* addD = new AdderDouble;
printf("addI = %18.1f\n", addI->add(11111111111111111.0, 1.0));
printf("addF = %18.1f\n", addF->add(11111111111111111.0, 1.0));
printf("addD = %18.1f\n", addD->add(11111111111111111.0, 1.0));
}
下面是一个在没有模板的情况下创建的具有相同功能的类的示例:
struct AdderBase
{
virtual double add(double a, double b)
{
return (a+b);
}
};
struct AdderInt : AdderBase
{
virtual double add(double a, double b)
{
return ((int)a+(int)b);
}
};
struct AdderFloat : AdderBase
{
virtual double add(double a, double b)
{
return ((float)a+(float)b);
}
};
struct AdderDouble : AdderBase
{
virtual double add(double a, double b)
{
return ((double)a+(double)b);
}
};
当以这两种不同的方式定义类 AdderBase、AdderInt、AdderFloat 或 AdderDouble 时,编译器是否会以不同的方式处理它们?
当类用作重载函数中的参数时,重载解析的不同顺序可能是一个不同的示例。
【问题讨论】:
-
“以这种方式定义的类有什么不同” 可能不是。但是为什么你需要基类成为模板的特化呢?有一个单独的类不是更易读吗?
-
"使用虚函数时,基类和所有派生类都使用单个类模板通常很方便" 为什么?这有什么“方便”的?
-
"对基类和所有派生类都使用一个类模板" -- 当你对这两个类使用相同的模板name基类和派生类,我不会将您的代码描述为使用单个类模板。从技术上讲确实如此,但仍有两个定义需要维护——一个用于
Adder <void>专业化,一个用于一般情况。这与对基类使用非模板并没有“感觉”不同。 -
您能否举例说明以不同方式处理类可能需要什么?你担心的是什么样的事情? (我可能期望某种模板语法错误,但
using别名应该可以防止这种情况发生。)
标签: c++ templates types virtual