首页 文章

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

提问于
浏览
1

我正在使用一个带有一些实用程序的类,这些实用程序被定义为静态方法,例如 .

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

不幸的是,我无法像预期的那样定义预编译时间,例如 .

const static int SSIMUtils::myI = 4;

因为它需要使用setDate方法 .

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

const static QDate LOW_DATE;

然后在.cpp文件中,在顶部,做类似的事情

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

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

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

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

5 回答

  • 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可用),它可以正常工作 .

  • 0

    它取决于初始化所需信息的来源,或者更确切地说,取决于何时可用 . 如果它始终可用,并且类型支持复制,那么您只需编写一个返回初始化类型的函数:

    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 开头新建的对象初始化 . 主要的不同之处在于客户端语法 . )

  • 0

    根据定义,您无法在运行时更改声明为常量的内容 .

    您可以获得最接近运行时常量初始化的是在类的构造函数初始化列表中初始化:

    SomeClass(int constantValue) :
        myConstant(constantValue)
    {
    ...
    }
    

    鉴于您正在构建静态类,您可能不会构建一个对象 . 您总是可以使用setter方法,该方法只允许设置一次值(在这种情况下,您显然无法声明字段const) .

  • 4

    顾名思义,它是一个常数,一旦初始化就不能(不应该)改变 . 您可以为常量成员变量赋值的唯一位置是在构造函数中(即没有奇怪的 const_cast ) .

  • 3

    您的QDate可能很容易构造 - 使用静态常量可能不会比每次调用函数时为该常量创建新日期更好 .

    为了回答这个问题,我们假设构造起来很复杂,静态常数是最好的想法 . 你可以简单地写:

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

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

    这将创建一个函数local static,它将被初始化一次,并在读取之前和调用函数时以线程安全的方式初始化 .

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

    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使用函数local-static提供的构造的简短方法是:

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

相关问题