我无法弄清楚哪种解决方案更好,因为我不清楚两者之间的区别。我想要一个包含一些可以在整个程序中自由使用的变量的文件。我的第一次尝试是:
头文件(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";
};
}
现在我的问题是:这些实现在变量实例数量方面有何不同?最好我希望每个变量只有一个实例。但是,这两种解决方案都可以做到这一点,并且在优化方面还有其他陷阱吗?
谢谢
答案 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。)