4

我有一个 C++ 类,它声明了一个静态成员。整个类包含在一个头文件中,我宁愿避免创建一个 .cpp 文件只是为了包含静态成员定义。我一直在尝试使用 static 关键字(在 C 意义上)和匿名命名空间,这两者都应该给出一个在头文件静态链接(asfaik)中声明的变量,但是这两种方法都不起作用,谁能给我一个解决方案问题?

struct ServiceType {} ;
struct Transport
{
    static ServiceType service ;
};

//error: definition of ‘Transport::service’ is not in namespace enclosing ‘Transport’
//namespace { ServiceType Transport::service ; }

//error: ‘static’ may not be used when defining a static data member
//static ServiceType Transport::service ;
4

4 回答 4

6

如果目标只是不必创建.cpp文件,最简单的解决方案可能是将静态数据成员包装在内联静态成员函数中。换句话说,类似:

struct Transport
{
    static ServiceType& service()
    {
        static ServiceType theData;
        return theData;
    }
};

当然,您必须使用语法service(),而不仅仅是service,来访问它。

于 2013-03-07T14:00:43.420 回答
2

您不能定义具有内部链接的静态成员。

如果您service在头文件中定义静态成员,您将在每个源中都有一个实例,其中包含此头文件。如果这不是问题,您可以将匿名命名空间包裹在整个struct Transport

namespace {
struct Transport
{
    static ServiceType service ;
};

ServiceType Transport::service;
}
于 2013-03-07T13:13:22.810 回答
0

匿名命名空间在整个编译单元中都是可见的。如果您在多个源文件中包含标头,您将得到多个名为 Transport::service 的符号。那是行不通的,因为你会symbol already defined从链接器中得到一个错误。

恐怕 C++ 的工作方式不允许您在不移动文件中service符号的定义的情况下摆脱这种情况.cpp

所以,在一个.cpp文件中,要么做,要么Transport::ServiceType service;如果你不想service成为命名空间的一部分,在extern ServiceType service;标题和.ServiceType service;.cpp

于 2013-03-07T13:12:36.997 回答
0

尝试

ServiceType Transport::service ;

这是错误的:

namespace { ServiceType Transport::service ; } //You are adding it in an unnamed namespace, rather than whatever namespace Transport is actually in - presumably the global namespace

这是错误的:

static ServiceType Transport::service ; // You dont need the static here, only in the struct.

如果您坚持将它放在标题中,我希望您会收到链接器错误

于 2013-03-07T13:15:23.340 回答