以下代码:
class A
{
public:
const int cx = 5;
};
这里,将为A的每个对象创建一个cx实例。这对我来说似乎是一种浪费,因为cx永远不会被修改。实际上,我没有看到任何理由为什么编译器不应该强制使const数据成员静态。有人可以向我解释一下吗?
答案 0 :(得分:9)
对于所有实例,const数据成员不必相同。您可以在构造函数中初始化它。
class A
{
public:
A(int n) :cx(n) {}
const int cx;
};
int main()
{
A a1(10);
A a2(100);
}
答案 1 :(得分:6)
实际上,我没有看到编译器不应该强制制作的任何理由 一个const数据成员static。
您是否认为cx
可能在构造函数中使用运行时已知的值进行初始化 - 并且在A
的不同实例之间有所不同?
const
成员不可能分配给他们,但有时会有一个不能改变其初始值的成员证明是有用的。
绝对不是最好的例子,而是为了说明这个想法:
struct Multiplier
{
const int factor;
Multiplier(int factor) : factor(factor) {}
int operator()( int val ) const
{
return val * factor;
}
};
std::vector<int> vec{1, 2, 3};
std::vector<int> vec2;
int i;
std::cin >> i;
std::transform( std::begin(vec), std::end(vec),
std::back_inserter(vec2), Multiplier(i) );
// vec2 contains multiples of the values of vec
答案 2 :(得分:1)
如果使用常量初始化值,如示例中所示, 它可能更好,它是静态的。但这并非总是如此 案子;有这样的事情经常发生:
class Matrix
{
const int myRowCount;
const int myColumnCount;
std::vector<double> myData;
// ...
public:
Matrix( int rows, int columns )
: myRowCount( rows )
, myColumnCount( columns )
, myData( rows * columns )
{
}
// ...
};
在这种情况下,const
清楚地表达了数量
任何给定实例中的行和列都不会更改。 (关于
另一方面,它阻止默认赋值运算符
产生。这可能是也可能不是好事。)
答案 3 :(得分:0)
使用非静态const成员有一些限制。
让我们说那个班级的员工。 首先,虽然编译器可以生成正确工作的复制构造函数,但它不能生成赋值运算符。如果程序创建两个Employee对象e1和e2,则语句e1 = e2将导致编译器诊断。此赋值无效,因为它隐式尝试更改const成员的值。 虽然你可以通过抛弃常数来赋予赋值运算符,但这又不是一个好主意。
另一个限制是很难为这个类提供有用的默认构造函数。如果要创建Employee对象数组,则默认构造函数是必不可少的。定义默认构造函数有点棘手;要记住的主要事情是const非静态数据成员在构造函数的初始化列表中初始化 - 您必须初始化所有这些成员。默认构造函数必须将dob字段设置为某个值,并且此值不能随后更改。所以构造的数组实际上是没用的