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

C++ 定义需要在运行时设置的const static,c++,class,static,C++,Class,Static,我正在使用一个类,其中包含一些定义为静态方法的实用程序,例如 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 SS

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

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
SSIMUtils::LOW_DATE.setDate(1970,1,1);
不幸的是,我不能像我说的int-eg那样在预编译时定义它

const static int SSIMUtils::myI = 4;
因为它需要使用setDate方法

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

const static QDate LOW_DATE;
然后在.cpp文件的顶部,执行如下操作

const static QDate LOW_DATE; // Need to set this somewhere to 1/1/1970
SSIMUtils::LOW_DATE.setDate(1970,1,1);
但这在语法上是不正确的。我最终想做的是在其他类中使用这个常数

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

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

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

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

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

假设您正在构建一个静态类,那么您可能还没有构建一个对象。您可以使用setter方法,该方法只允许设置一次值,在这种情况下,您显然不能声明字段常量。

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

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

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

假设您正在构建一个静态类,那么您可能还没有构建一个对象。您可以使用setter方法,该方法只允许设置一次值,在这种情况下,您显然不能声明字段const。

顾名思义,它是一个常量,初始化后不应更改。唯一可以为常量成员变量赋值的地方是构造函数中,也就是说,没有奇怪的常量转换。

顾名思义,它是一个常量,初始化后不应更改。唯一可以为常量成员变量赋值的地方是构造函数,也就是说,没有奇怪的常量强制转换。

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

必须按以下方式声明静态常量:

myclass.h:

#include <QDate>

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

我使用std::string而不是QDate测试了这个问题,现在没有可用的QT,它可以按照您的需要工作。

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

必须按以下方式声明静态常量:

myclass.h:

#include <QDate>

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

我使用std::string而不是QDate-no-QT测试了这一点,它可以按照您的需要工作。

这取决于 初始化是在可用时进行的。如果是 始终可用,并且类型支持复制,则您可以 只需编写一个返回初始化类型的函数:

namespace {
MyType getInitialized()
{
    MyType results;
    //  ...
    return results;
}
}

static MyType const lowDate( getInitialized() );
如果它不支持复制,您可以从中派生,提供 专门的构造器:

class MyTypeInitialized : public MyType
{
public:
    MyTypeInitialized()
    {
        //  ...
    }
};
MyTypeInitialized lowDate;
这样做的缺点是将真实类型从 客户端代码,但在其他方面工作良好

如果信息在以后才可用;e、 视情况而定 在命令行参数上,则可能必须使用 单例习惯用法,其中有两个实例函数: 其中一个接受初始化所需的参数, 必须先打电话。或者,这甚至可能是过度杀戮;信息技术 可能足以拥有全局std::unique_ptr lowDate;,然后用一个在 主程序的开始。主要区别在于客户端
语法。

它取决于 初始化是在可用时进行的。如果是 始终可用,并且类型支持复制,则您可以 只需编写一个返回初始化类型的函数:

namespace {
MyType getInitialized()
{
    MyType results;
    //  ...
    return results;
}
}

static MyType const lowDate( getInitialized() );
如果它不支持复制,您可以从中派生,提供 专门的构造器:

class MyTypeInitialized : public MyType
{
public:
    MyTypeInitialized()
    {
        //  ...
    }
};
MyTypeInitialized lowDate;
这样做的缺点是将真实类型从 客户端代码,但在其他方面工作良好

如果信息在以后才可用;e、 视情况而定 在命令行参数上,则可能必须使用 单例习惯用法,其中有两个实例函数: 其中一个接受初始化所需的参数, 必须先打电话。或者,这甚至可能是过度杀戮;信息技术 可能足以拥有全局std::unique_ptr lowDate;,然后用一个在 主程序的开始。主要区别在于客户端
语法。

您的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;
}

构造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;
}

QDate有一个与setDate等效的构造函数。QDate有一个与setDate等效的构造函数。谢谢Saanti。我想我将使用类构造函数来设置它。谢谢Saanti。我想我会使用类构造函数来设置它。如果对象本身声明为静态,则奇怪的常量转换将导致未定义的行为。如果对象本身声明为静态,则奇怪的常量转换将导致未定义的行为。感谢Justin的选项和解释。皮特:谢谢你的选择和解释,贾斯汀。皮特