【问题标题】:Best way to define class-scoped constant in C++在 C++ 中定义类范围常量的最佳方法
【发布时间】:2020-04-22 15:11:07
【问题描述】:

我需要在cpp 文件中使用一些常量值,该文件与一个类相关并且不会在它之外使用。

我想出了几种方法:

方法一:static const.cpp文件中

static const int a = 100; // <<<

int Class::foo() const
{
    return a + 10;
}

int Class::bar() const
{
    return a - 10;
}

如果我做对了,我也可以省略 static 关键字,因为 const 在此上下文中自动暗示内部链接。
如果我错了,请纠正我

方法 2:匿名命名空间 (C++11)

与上一个基本相同,但是:

namespace
{
    const int a = 100;
}

我相信这种方法是在 C++11 中声明此类作用域常量的首选方法。
再次,如果我错了,请纠正我

方法3:static const.h文件中

class Class
{
public:
    int foo() const;
    int bar() const;
protected:
    static const int a = 100; // <<<
};

方法4:.h中的非静态const (C++11)

class Class
{
public:
    int foo() const;
    int bar() const;
protected:
    const int a = 100; // <<<
};

或者像这样:const int a{100}。我认为 POD 类型没有区别。
再一次,如果我错了,请纠正我

方法五:初始化列表

class Class
{
public:
    Class() : a(100) {} // <<<
    int foo() const;
    int bar() const;
protected:
    const int a;
};

总结

我想我不能使用方法 1 和 2,因为如果我需要创建子类,它们会失败。

另外,我认为如果有很多重载的构造函数,方法5将很难维护。

虽然这个问题可能被认为是基于意见的,但我主要是想弄清楚这些方法的优缺点,可能还有其他一些可能的解决方案。

【问题讨论】:

  • 在 #4 和 #5 中,您将班级规模至少增加 sizeof(int)
  • 我认为#3 最适合您的用例。但在我看来,将其设为static constexpr 会更好。
  • 使用最适合您当前情况的那个 (#2),如果您将来需要,可以更改它。除了真正微不足道的问题外,没有任何“理想的现在、永远和永远”的解决方案。
  • 是否允许子类改变这个常量的值?
  • #1 & #2 是相同的,不能被认为是“类作用域”——它可以从同一个文件中的任何地方访问。

标签: c++ c++11 static constants


【解决方案1】:

对于普通的全局变量,const 确实暗示了static(但请注意,const char *f; 不是 const),所以有或没有static 的#1 确实是一样的。 (这确实是一个错误,作为constexpr inline 的模拟包含在变量之前很多年。)#2 也是相同的(仅在 classes 也可以在匿名中声明命名空间,但不能声明为static)。

这些对于派生类来说本质上并不坏:它们将常量限制在一个源文件中,该文件可以为尽可能少或尽可能多的类定义方法。您也可以将它们放在.hpp 文件中,尽管首选类成员是合理的。

对于#3,请注意变量不需要在类定义中初始化。这样做可以让它在包含标题的每个文件中的常量表达式中使用,在这种情况下,现代风格(支持非整数变量)是使用constexpr

#4 和 #5 为每个类对象添加一个成员,最好避免使用 - 考虑它们禁用默认的 assignment 运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-26
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2021-08-21
    相关资源
    最近更新 更多