定义需要在运行时设置的 const static

Posted

技术标签:

【中文标题】定义需要在运行时设置的 const static【英文标题】:Defining const static that needs setting up at runtime 【发布时间】:2013-05-14 08:31:40 【问题描述】:

我正在使用一个类,其中包含一些定义为静态方法的实用程序,例如。

QDate SSIMUtils::ConvertSSIMDate(QString s) 
    QDate rtnDt;
    //...conversion code
    return rtnDt;

我想在这个类中定义一些常量,例如。 LOW_DATE 并且正在考虑放入类似的东西

const static QDate LOW_DATE; // Need to set this somewhere to 1/1/1970

不幸的是,我不能像我所说的 int 那样定义它的预编译时间。

const static int SSIMUtils::myI = 4;

因为它需要使用 setDate 方法。

我的问题是我应该如何定义一个需要按代码设置的静态常量,因为该常量需要初始化。我一直在考虑在 .h 文件中定义它,例如。

const static QDate LOW_DATE;

然后在 .cpp 文件的顶部,执行类似的操作

SSIMUtils::LOW_DATE.setDate(1970,1,1);

但这在语法上是不正确的。我最终想做的是在其他类中使用这个常量,例如。

if (myQDate.compare(SSIMUtils::LOW_DATE)==0) 
    // do something.

在您需要在运行时调整的静态类中设置常量值的正确方法是什么,即。像构造函数?

【问题讨论】:

QDate 有一个等价于 setDate 的构造函数。 【参考方案1】:

正如我在评论中提到的,QDate 有一个等效于 setDate() 的构造函数,它允许初始化一个“const”对象。

您必须通过以下方式声明您的静态常量:

myclass.h:

#include <QDate>

class myclass 
public:
    const static QDate CONST_DATE;
;

myclass.cpp:

#include "myclass.h"

const QDate myclass::CONST_DATE(1970, 1, 1);

我使用 std::string 而不是 QDate 对此进行了测试(目前没有可用的 QT),它可以按照您的意愿工作。

【讨论】:

【参考方案2】:

这取决于所需的信息在哪里 初始化来了,或者更确切地说,当它可用时。如果它是 始终可用,并且类型支持复制,那么你可以 只需编写一个返回初始化类型的函数:

namespace 
MyType getInitialized()

    MyType results;
    //  ...
    return results;



static MyType const lowDate( getInitialized() );

如果它不支持复制,你可以从中派生,提供 一个专门的构造函数:

class MyTypeInitialized : public MyType

public:
    MyTypeInitialized()
    
        //  ...
    
;
MyTypeInitialized lowDate;

这样做的缺点是掩盖了真实类型 客户端代码,但在其他方面运行良好。

如果信息直到稍后才可用;例如这取决于 在命令行参数上,那么您可能必须使用 单例习语,您有两个 instance 函数: 其中一个需要初始化的必要参数, 并且必须首先调用。 (或者这甚至可能是矫枉过正;它 拥有一个全局std::unique_ptr<MyType const> lowDate; 可能就足够了,并使用新的对象对其进行初始化 main 的开头。主要区别在于客户端 语法。)

【讨论】:

【参考方案3】:

根据定义,您不能在运行时更改声明为常量的内容。

最接近运行时常量初始化的方法是在一个类中初始化' 构造函数初始化列表:

SomeClass(int constantValue) :
    myConstant(constantValue)

...

鉴于您正在构建一个静态类,但您可能并未构建一个对象。您总是可以求助于只允许设置一次值的 setter 方法(在这种情况下,您显然不能声明字段 const)。

【讨论】:

谢谢桑蒂。我想我会使用类构造函数来设置它。【参考方案4】:

顾名思义,它是一个常量,一旦初始化就不能(不应该)改变。唯一可以为常量成员变量赋值的地方是在构造函数中(也就是说,没有奇怪的const_casts)。

【讨论】:

如果对象本身被声明为静态,那么奇怪的const_cast 将导致未定义的行为。【参考方案5】:

您的 QDate 构建起来可能很简单——使用静态常量可能并不比每次调用函数时为该常量创建一个新日期更好。

为了回答这个问题,我们假设它的构造很复杂,并且最好使用静态常量。你可以简单地写:

QDate SSIMUtils::ConvertSSIMDate(QString s) 
    static const QDate LOW_DATE( /* ...construct it... */ );
    QDate rtnDt;
    //...conversion code
    return rtnDt;

注意:看起来 SirDarius 解释了如何直接构造这种类型,而无需中间 (+1),尽管函数局部静态常量通常比全局常量好得多,因为全局常量会导致一些非常C++ 中的棘手初始化问题。

这将创建一个函数局部静态,该函数将在读取之前和调用函数时以线程安全的方式初始化一次。

如果无法轻松构造实例,有时可以使用复制构造函数进行初始化,然后创建辅助函数:

QDate SSIMUtils::ConvertSSIMDate(QString s) 
    struct F  static QDate Low()  return ...;  ;
    static const QDate LOW_DATE(F::Low()); // << initialize the constant using the copy ctor
    QDate rtnDt;
    //...conversion code
    return rtnDt;

因此,使用 SirDarius 提供的使用 function-local-static 的构造的简短方法是:

QDate SSIMUtils::ConvertSSIMDate(QString s) 
    static const QDate LOW_DATE(1970, 1, 1);
    QDate rtnDt;
    //...conversion code
    return rtnDt;

【讨论】:

感谢贾斯汀的选项和解释。皮特

以上是关于定义需要在运行时设置的 const static的主要内容,如果未能解决你的问题,请参考以下文章

static和const变量有什么区别?

OC中extern、static、const和宏定义

const、define、static、extern

const对象默认是static的,而不是extern的

PHP中const,static,public,private,protected的区别

OC 中static、const理解