【问题标题】:C++ Constructor for first instance only?仅用于第一个实例的 C++ 构造函数?
【发布时间】:2015-12-24 04:53:41
【问题描述】:

所以我有一个带有静态变量的类,它们是静态的原因是为了(虽然它可能看起来微不足道)效率(只需要加载一次,减少同一文件内存中存储的冗余)。

无论如何我想知道,有没有办法检查变量是否已加载?

或者有没有办法在第一次创建此类的实例时调用特定的构造函数,并在其他实例存在时使用另一个构造函数?

如果这些都不合适,解决办法是什么?

【问题讨论】:

  • 静态成员变量在你的main函数被调用之前被构造和初始化。如果main已经被调用,那么静态成员变量已经被“加载”了。
  • 有一个用于高效代码设计的 SingleTon 设计模式,请通过这个:: sourcemaking.com/design_patterns/singleton/cpp/1
  • @Nishant_b9: ...然后把它当作一个糟糕的想法丢弃,忘记你曾经读过它。
  • 感谢您的回复,@Joachim Pileborg 我不知道必须在调用 main 之前设置静态成员变量,我在我的 .cpp 中初始化它们而没有值。 @Nishant 我知道 singelton 模式,但我觉得它在这里不适用,因为我仍然希望资源可以在需要时在不同实例之间进行更改。

标签: c++ performance processing-efficiency


【解决方案1】:

如果您的静态成员是私有的,并且在与您的所有类的成员函数相同的翻译单元中初始化,则标准保证静态成员在使用之前将被初始化。见:When are static C++ class members initialized?

在其他情况下,此保证对您没有帮助(例如,从另一个翻译单元或从内联成员函数访问非私有静态成员)。

您可以使用isInitialized 标志玩游戏,但请注意,如果没有进一步的工作,这不是线程安全的。

C++ FAQ 建议将静态类实例包装在函数中,这样可以确保它们在首次使用时被初始化。例如:

Fred& x()
{
    static Fred* ans = new Fred();
    return *ans;
}

来源:https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use

【讨论】:

    【解决方案2】:

    给你:

    class Test {
      static bool isInitialized;
    public:
      Test() {
        if (!isInitialized) {
          // do whatever you need here
          // ...
          isInitialized = true;
        }
      }
    };
    
    bool Test::isInitialized = false;
    

    【讨论】:

    • @MarcusMüller:再来一次?
    • 约翰,很抱歉 :) 我只是期待看到这种模式(检查类 decl 中的静态集);我也误读了你的代码,所以我要撤回我的投票。
    【解决方案3】:

    你可以这样做:

    struct StaticData
    {
      // some variables
    };
    
    class YourClass
    {
    public:
        YourClass(/*..*/) {
            if (staticData == nullptr) {
                staticData = std::make_unique<StaticData>(/*..*/)
            }
        }
    private:
        static std::unique_ptr<StaticData> staticData;
    };
    
    static std::unique_ptr<StaticData> YourClass::staticData;
    

    【讨论】:

    • 或者只是正常实例化它,而不需要任何动态分配使您的代码复杂化。
    • @LightnessRacesinOrbit:我怀疑 OP 会使用一些提供的参数对其进行初始化。但否则你是对的。
    猜你喜欢
    • 2014-08-28
    • 2011-04-19
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2020-10-19
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多