【问题标题】:What are the downsides to accessing a std::map<std::string, int> using string literals?使用字符串文字访问 std::map<std::string, int> 有什么缺点?
【发布时间】:2022-01-18 23:11:08
【问题描述】:

我用 C++ 编写了一个 ResourceManager 类,其中包含一个 std::map&lt;std::string, Resource&gt;。然后,我当前的代码使用字符串文字访问这些方法,例如:

// ResourceManager.h
class ResourceManager {
    private:
        std::map<std::string, Resource>

    public:
        void loadResource(std::string_view resourceName, std::string_view fileName); 
        const Resource& getResource(std::string_view resourceName) const;
}

// a.cpp
resourceManager.loadResource("background image", "background_image.png")

// b.cpp
resourceManager.getResource("background image")

这会是个问题吗?我应该用constants.h 文件中定义的常量替换所有这些字符串文字吗?在这种情况下,我应该只使用enum 作为地图的键吗?

【问题讨论】:

  • 这更像是一个最佳实践问题。对于它的价值,是的,要么使用枚举,要么使用常量 vbl
  • 像往常一样,这取决于。使用字符串文字会导致拼写错误。另一方面,拥有一个全局枚举将使您在添加新枚举值时重新编译所有内容。
  • 我看到的使用字符串文字的主要问题是你在重复信息。这引入了不必要的错误来源。请参阅Don't Repeat Yourself(DRY 负责人)。
  • 总是字符串文字吗?也许你可以使用这样的编译时间图:github.com/serge-sans-paille/frozen

标签: c++ stdmap stdstring string-literals


【解决方案1】:

与使用魔术常量的任何其他情况一样,它可能会导致代码脆弱,,代码可能会损坏。特别是,考虑如果 "background image" 资源被加载一次并从多个不同的位置检索,可能跨越许多源文件会发生什么。如果资源在loadResource 调用中被重命名,但您忘记更改getResource 调用之一,则程序将出现错误。使用枚举或命名常量可以避免这个问题。

使用枚举作为键的另一个好处是它非常高效:在查找值的过程中生成的任何键副本都很便宜。这与您当前的代码形成对比,您可能正在复制 resourceName 以执行查找(尽管使用透明比较器可以避免这种情况)。

【讨论】:

    猜你喜欢
    • 2019-10-06
    • 2021-12-18
    • 1970-01-01
    • 2011-11-04
    • 2017-01-26
    • 1970-01-01
    • 2018-02-12
    • 2020-05-15
    • 1970-01-01
    相关资源
    最近更新 更多