做得更好:
const int MY_CONST = 20; // global constant in the program
class A {
// uses MY_CONST all over the class implementation and definition
}
还是这个?
const int MY_CONST = 20; // global constant in the program
template<int my_const>
class A {
//uses my_const only and never MY_CONST
};
//A<MY_CONST> used later in the program
其中一种模式比另一种更好吗?为什么? 感谢
答案 0 :(得分:3)
除非在类之外的其他地方使用该全局常量,否则我将不使用这些方法并使常量成为A
的成员:
class A {
public:
static const int MY_CONST = 20;
};
const int A::MY_CONST; // Possibly need definition also
然后在代码中使用A::MY_CONST
。
我唯一一次使用模板是因为某些原因需要根据实例更改值。
template <int I>
class A
{
public:
static const int MY_CONST = I;
};
template <int I>
const int A<I>::MY_CONST; // Definition
然后创建如下的实例:
A<1> a1;
A<2> a2;
答案 1 :(得分:2)
如果有必要实例化第二种解决方案是明智的A<MY_CONST + 1>
或A<0>
,或MY_CONST
以外的任何其他值。但是,如果A
严格设计为与一个值一起使用,那么你就不会从中获得任何东西。在这方面,第一个解决方案为您提供了所需的一切。
答案 2 :(得分:0)
一种看待它的方法是你要向A
引入一个依赖(仅限于一个数字,而不是任何有行为的东西,但仍然是一种依赖),问题是是否要通过模板参数注入该依赖项,或让类通过命名的const对象拉入依赖项。
我可以看到该模板对于测试类A
非常有用 - 您希望编写该类以使用任何值,以便您可以在将来更改该值并确保不会立即得到测试失败并且必须修复错误。
因此,您可以编写模板并使用许多不同的值对其进行测试,即使没有“真正的”程序会使用模板的多个实例化。
显然,还有其他方法可以编写一个行,该行的行为取决于整数值,并对其进行测试。例如,您可以使用宏并让测试工具多次编译代码,或者您可以使MY_CONST
成为外部值并将代码链接到包含不同值的不同目标文件,或者您可以使{{1}将值存储为数据成员(甚至是静态数据成员)。
哪些适合您,取决于类将如何使用该值,但由于模板参数是一个整数常量表达式,因此A
适用于大多数用途。你不能拿模板参数的地址,这是唯一让你想到的东西。
答案 3 :(得分:0)
我总是删除全局变量。让我们区分两种情况,MY_CONST
是
实施细节,在这种情况下,我希望将其设为私有常量
class A
{
private:
static int const MY_CONST = 20;
};
或类接口的一部分在这种情况下,我更愿意将其作为模板参数并将其作为公共成员提供
template<int N>
class A
{
public:
static int const MY_CONST = N;
};
这样,用户不仅可以阅读,还可以“编写”(在编译时)MY_CONST
。如果用户不想指定除N
的默认值之外的任何内容,则可以提供默认模板参数,或者提供简单的typedef
typedef A<20> DefaultA;