假设我有一个源文件A.cpp:

#include<string>

struct A {
  static const std::string a;
  static const std::string b;
  static const std::string c;
};

const std::string A::a{"1"};
const std::string A::b{"2"};
const std::string A::c{"3"};

并希望在另一个翻译单元中使用A::b。通常的方法是将A.cpp分为声明A.hpp和定义,包括第一个。
#include<iostream>
#include<A.hpp>

int main(){
  std::cout << A::b << "\n";
  return 0;
}

当然可以,但是我要避免包含类声明,因为在我的情况下A很大并且具有繁琐的依赖关系。

理想情况下,我想拥有类似
struct A;
external const std::string A::m;

但这会产生不完整的类型错误。

可以依靠通过其他非类全局变量进行链接。
const std::string A::b{"2"};
const std::string* bptr{&A::b};

并在另一个源文件中声明为
extern const std::string* bptr;

这是正确的方法,但对我来说却很难看,因为需要引入冗余实体。

对我有用的另一个技巧。
struct A {
  static const std::string b;
};

int main(){
  std::cout << A::b << "\n";
  return 0;
}

看起来不错,但很笨拙,即使是私有(private)成员(member)也可以使用。合法吗就是说,有什么定义这种行为的东西吗?

最佳答案

最后显示的技巧可能是最糟糕的破解,并且有一天会适得其反-因为它“掩盖”了另一个定义。这里没有“中间”(除了许多“hacks”之外),要么使类定义完整显示,要么将字符串定义移出类。

看起来不错,但很笨拙,即使是私有(private)成员(member)也可以使用。合法吗

取决于上下文,如果第三个单元同时使用了这两个单元,那么您将回到原始问题上。它之所以成为私有(private)的原因是另一种定义,因此一开始就不是私有(private)的。

关于c++ - 链接类静态变量而不包含整个类声明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53225630/

10-11 23:08
查看更多