草庐IT

java - C++ 复杂静态初始化逻辑的最佳实践

coder 2024-02-08 原文

我长期使用 Java,但对 C++ 比较陌生。所以在 Java 中,如果在类级别有一些复杂的静态对象(在 Java 中一切都在类级别),我们可以简单地使用静态 block 来初始化它。例如

public class MyClass extends MyBase {

    public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> ();

    static {
        AComplexClass first = ComplexClassFactory.createComplexType1();
        first.configure("Something", "Something");

        STATIC_MAP.put("key1", first);

        // do some more
    }
}

但是鉴于初始化 C++ 静态变量的限制,如果我想定义相同的 STATIC_MAP,这可能太复杂了,这似乎我需要在 .cpp 中命名变量每个文件 AComplexClass对象然后放到映射中,在代码中产生相当多的垃圾,也有可能让其他类意外地引用它们。

那么,对于这种静态初始化逻辑,C++ 的最佳实践是什么?我认为这是使用相同的策略,但可能是其他风格。

最佳答案

.cpp 文件中的静态初始化

您可以在 C++ 中做类似的事情,但您需要在 .cpp 文件中进行初始化。您可以将初始化推迟到一个函数,这样您就可以进行任何您想要的初始化:

MyClass.h

#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

class MyClass {
public:
  const static MyMap STATIC_MAP;
};

MyClass.cpp

#include "MyClass.h"

namespace {    
  MyMap createMap() {
    MyMap map;
    auto first = createComplexType1();
    first.configure("Something", "Something");

    map.emplace("key1", std::move(first));

    // do some more

    return map;
  }
}

const MyMap MyClass::STATIC_MAP = createMap();

main.cpp

#include "MyClass.h"

int main() {
  auto object = MyClass::STATIC_MAP.at("key1");
}

因为 operator[] 需要非常量访问,所以我使用了 at()

您需要注意的一件事是 static initialization order fiasco这基本上意味着您应该避免依赖另一个 .cpp 文件中的任何静态初始化。

静态局部变量

避免静态初始化顺序失败的一种方法是使您的映射成为函数中的静态局部变量。这还有一个好处,如果您愿意,您可以在 .h 文件中定义所有内容:

MyClass.h

#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

MyMap createMap() {
  // as before ...
}

class MyClass {
public:
  static const AComplexClass& STATIC_MAP(const std::string& key) {
    const static MyMap map = createMap();

    // Could return the map by reference but may as well use it in this
    // function to make the syntax slightly simpler for the calling code.
    return map.at(key);
  }
};

main.cpp

#include "MyClass.h"

int main() {
  auto object = MyClass::STATIC_MAP("key1");
}

静态局部变量在第一次使用时会被初始化。

关于java - C++ 复杂静态初始化逻辑的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31737191/

有关java - C++ 复杂静态初始化逻辑的最佳实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  8. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  9. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐