内联静态const与静态const变量

时间:2019-02-12 07:51:58

标签: c++

我无法弄清楚哪种解决方案更好,因为我不清楚两者之间的区别。我想要一个包含一些可以在整个程序中自由使用的变量的文件。我的第一次尝试是:

头文件(Hosts.h)

#pragma once

#include <string>

namespace Some::Namespace {

using std::string;

class Hosts {
public:
    static const unsigned int SOME_DEVICE_PORT;
    static const string SOME_DEVICE_IP;
};
}

实施文件(Hosts.cpp)

#include <Network/Hosts.h>

namespace Some::Namespace {
    const unsigned int Hosts::SOME_DEVICE_PORT = 10100;
    const string Hosts::SOME_DEVICE_IP = "192.168.1.1";
}

然后我知道了 inline 关键字,它将使实现文件变得多余,您将能够在头文件中单独定义变量-就像这样:

带有内联(Hosts.h)的头文件

#pragma once

#include <string>

namespace Some::Namespace {

using std::string;

class Hosts {
public:
    static const unsigned int SOME_DEVICE_PORT = 10100;
    inline static const string SOME_DEVICE_IP = "192.168.1.1";
};
}

现在我的问题是:这些实现在变量实例数量方面有何不同?最好我希望每个变量只有一个实例。但是,这两种解决方案都可以做到这一点,并且在优化方面还有其他陷阱吗?

谢谢

2 个答案:

答案 0 :(得分:3)

扩展Mayur答案,这两种方法非常相似。 两者之间的主要区别是在库中使用内联静态变量(.dll s等)。

使用inline变量,在compile phase期间,每个使用翻译单元的地方都会有一个实例,然后linker会删除除一个实例之外的所有实例,并引用所有实例将翻译单元转换为唯一未删除的实例。

使用non-inline变量,将只有一个变量实例,然后所有翻译单元都将引用该变量。

在一个模块(.exe,.dll ...)中,这两个用例的行为完全相同。

但是,当将多个.dll与.exe和inline变量链接在一起时,每个模块将具有一个实例,因此每个模块都将引用其自己的实例。这可能是(或可能不是)一个问题。由于您声明了它们const,因此变量value不会有问题,但是如果您使用它的地址进行比较或某些操作(对于不同的模块而言),则可能会遇到问题。不同的地址。

non-inline变量不会发生这种情况,因为您应该export来自一个共享模块的变量,并从所有其他模块引用它,而整个模块只有一个实例。 / p>

答案 1 :(得分:2)

声明为内联的变量与声明为inline的函数具有相同的语义,可以在多个翻译单元中相同地对其进行定义,必须在使用它的每个翻译单元中对其进行定义,并且其行为该程序就好像只有一个变量一样。

struct MyClass
{
    static const int sValue;
};
inline int const MyClass::sValue = 777;

甚至:

struct MyClass
{
    inline static const int sValue = 777;
};

另外,请注意,constexpr变量是inline的隐式变量,因此无需使用constexpr inline myVar = 10;

ref。)