非静态const数据成员有什么意义?

时间:2014-11-03 17:59:13

标签: c++ static const

以下代码:

class A
{
public:
    const int cx = 5;
};

这里,将为A的每个对象创建一个cx实例。这对我来说似乎是一种浪费,因为cx永远不会被修改。实际上,我没有看到任何理由为什么编译器不应该强制使const数据成员静态。有人可以向我解释一下吗?

4 个答案:

答案 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字段设置为某个值,并且此值不能随后更改。所以构造的数组实际上是没用的