简体   繁体   English

我可以在 class header 文件中定义一个 class 的 const static 实例吗

[英]Can I define a const static instance of a class in the class header file

Is it possible to declare and define a const static instance of a class in the class header file.是否可以在 class header 文件中声明和定义 class 的 const static 实例。

I want to do something like this (from this similar question):我想做这样的事情(来自这个类似的问题):

class PlaceID {

public:

    inline PlaceID(const std::string placeName):mPlaceName(placeName) {}

    const static PlaceID OUTSIDE;

private:
    std::string mPlaceName;
};

const PlaceID PlaceID::OUTSIDE = PlaceID("");

This would work if the definition of PlaceID::OUTSIDE was in a source file, but if it's in a header file that is include in multiple location it causes an link error because PlaceID::OUTSIDE is then defined multiple times.如果 PlaceID::OUTSIDE 的定义在源文件中,这将起作用,但如果它在包含在多个位置的 header 文件中,则会导致链接错误,因为 PlaceID::OUTSIDE 随后被定义了多次。

I'd like to define it in the header file for two reasons.我想在 header 文件中定义它有两个原因。 First, this will be part of a library and I'd like the library to be header file only.首先,这将是库的一部分,我希望库只是 header 文件。

Second and this is the most important one I want the compiler to be allowed to "inline" the uses of this instance.其次,这是最重要的一点,我希望允许编译器“内联”该实例的使用。 The class in question (not the one used as an example here) is a wrapper around a primitive type with all methods inlined in order to offer the same performance as the primitive type would.所讨论的 class(不是此处用作示例的那个)是原始类型的包装器,所有方法都内联以提供与原始类型相同的性能。 If I place the definition of this instance in a source file, the compiler will not know it's value at compilation time and won't be able to apply some optimisations.如果我将此实例的定义放在源文件中,编译器将不知道它在编译时的值,也无法应用一些优化。

Thanks.谢谢。

In C++17, variables can be marked as inline : 在C ++ 17中,变量可以标记为inline

class PlaceID 
{
    inline const static PlaceID OUTSIDE{""};
    // ...
};

Before C++14, you can use a function instead: 在C ++ 14之前,您可以改用函数:

class PlaceID 
{
    static PlaceID OUTSIDE() { return PlaceID{""}; }
    // ...
};

...or... ...要么...

class PlaceID 
{
    static PlaceID OUTSIDE() 
    { 
        static PlaceID result{""};
        return result;
    }

    // ...
};

...depending on whether or not you want a single PlaceID instance. ...取决于您是否要使用一个PlaceID实例。


Alternatively, you can templatize PlaceID over a dummy parameter in order to inline the definition of OUTSIDE in an header: 另外,您可以在虚拟参数上模板化PlaceID以便在标头中内联OUTSIDE的定义:

template <typename>
struct PlaceID_
{
    inline PlaceID_(const char*) { }
    const static PlaceID_ OUTSIDE;
};

template <typename T>
const PlaceID_<T> PlaceID_<T>::OUTSIDE{""};

using PlaceID = PlaceID_<void>;

This works because templates are implicitly inline . 这是可行的,因为模板是隐式inline See How do inline variables work? 请参阅内联变量如何工作? for more details. 更多细节。

live example on wandbox.org wandbox.org上的实时示例


Also consider marking PlaceID::PlaceID(const char*) as constexpr if possible so that OUTSIDE can be marked constexpr as well. 如果可能的话,还可以考虑将PlaceID::PlaceID(const char*)标记为constexpr ,以便也可以将OUTSIDE标记为constexpr Obviously this will not work if you decide to use std::string . 显然,如果您决定使用std::string则此方法将无效。

that is include in multiple location包含在多个位置

You can stop your header from being included multiple times(and causing your problem(DISCLAIMER: I have not tested it.)) by this(which is commonly used by a lot of libraries)你可以阻止你的 header 被多次包含(并导致你的问题(免责声明:我没有测试过它。))通过这个(很多图书馆常用)

a.hpp

#ifndef LIBRARY_A
#define LIBRARY_A
//define other things
#endif

replace LIBRARY_A for an ID of your choice(note it can't conflict with other libraries so avoid names like SOUND_SYSTEM , but rather SOUND_LIBRARY_FOO with FOO replaced by your project name/your name)LIBRARY_A替换为您选择的 ID(请注意,它不能与其他库冲突,因此请避免使用SOUND_SYSTEMFOO的名称,而是将SOUND_LIBRARY_FOO替换为您的项目名称/您的名称)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM