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

不幸的是,我不能像我所说的那样定义它的预编译时间,例如 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.
}

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

4

5 回答 5

4

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

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

myclass.h:

#include <QDate>

class myclass {
public:
    const static QDate CONST_DATE;
};

我的类.cpp:

#include "myclass.h"

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

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

于 2013-05-14T08:44:59.133 回答
3

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

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。主要的区别在于客户端语法。)

于 2013-05-14T08:45:16.613 回答
1

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

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

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

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

于 2013-05-14T08:41:02.943 回答
0

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

于 2013-05-14T08:41:17.680 回答
0

您的 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;
}
于 2013-05-14T09:06:02.793 回答