【问题标题】:Initializing static struct tm in a class在类中初始化静态结构 tm
【发布时间】:2011-01-07 11:38:21
【问题描述】:

我想将 tm 结构用作类中的静态变量。花了一整天的时间阅读和尝试,但它仍然无法工作:(如果有人能指出我做错了什么,将不胜感激

在我的班级中,在 Public 下,我已将其声明为:

static struct tm *dataTime;

在main.cpp中,我尝试用系统时间来定义和初始化它临时测试一下(实际时间要在运行时输入)

time_t rawTime;
time ( &rawTime );
tm Indice::dataTime = localtime(&rawTime);

但似乎我不能在函数之外使用 time()。

main.cpp:28:错误:预期 构造函数、析构函数或类型 '(' 标记之前的转换

如何在类的静态 tm 中初始化值?

【问题讨论】:

  • dataTime 是 tm* 还是 tm?
  • 最好不要是tm*,因为localtime返回的是静态实例。

标签: c++ class static struct ctime


【解决方案1】:

你不能在函数之外任意调用函数。要么在 main() 函数中进行初始化,要么在 tm 结构周围创建一个包装类,并使用一个进行初始化的构造函数。

【讨论】:

    【解决方案2】:

    您可以将以上内容包装在一个函数中:

    tm initTm() {
        time_t rawTime;
        ::time(&rawTime);
        return *::localtime(&rawTime);
    }
    
    tm Indice::dataTime = initTm();
    

    为避免可能的链接问题,请将函数设为静态或将其置于未命名的命名空间中。

    【讨论】:

    • 呵呵,太多了。我只是傻,匿名和未命名的意思是一样的,但不是按照标准。 :|愚蠢的委员会。
    【解决方案3】:
    struct tm get_current_localtime() {
        time_t now = time(0);
        return *localtime(&now);
    }
    
    struct tm Indice::dataTime = get_current_localtime();
    

    【讨论】:

      【解决方案4】:

      将整个东西包装在一个函数中,并用它来初始化你的静态成员:

      tm gettime() {
          time_t rawTime;
          time ( &rawTime );
          return localtime(&rawTime);
      }
      
      tm Indice::dataTime = gettime();
      

      而且您不需要(因此也不应该)在 C++ 中为结构使用添加 struct 前缀:tm 就足够了,不需要 struct tm。

      【讨论】:

        【解决方案5】:

        另请注意,您的 struct tm 是指向 tm 结构的指针。 localtime 的返回是一个单例指针,当您或其他任何人再次调用 localtime 时,其内容会发生变化。

        【讨论】:

        • localtime 返回一个静态实例。因此,它不是线程安全的或可重入的。还有localtime_r 以提高健壮性。
        • 我的回答通过直接复制其内容来稍微补偿它,但仍然不能以任何方式使其成为线程安全的。
        • 没有意识到这一点。已更新,谢谢。这是多么愚蠢的模式。
        【解决方案6】:

        添加这个:

        namespace {
          class Initializer {
            public:
              Initializer() { 
                time_t rawtime; time(&rawtime);
                YourClass::dataTime = localtime(&rawtime);
              }
          };
          static Initializer myinit();
        }
        

        在运行时初始化目标文件时,会调用构造函数 Initializer(),然后根据需要设置“全局”变量 dataTime。请注意,匿名命名空间构造有助于防止名称 Initializer 和 myinit 的潜在冲突。

        【讨论】:

        • 这种方法比使用上面提到的函数直接初始化有什么优势
        猜你喜欢
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 2015-10-10
        • 2021-01-31
        • 2015-10-30
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        相关资源
        最近更新 更多