【问题标题】:unresolved external symbol when static variable is defined inside the class declaration [duplicate]在类声明中定义静态变量时未解析的外部符号[重复]
【发布时间】:2014-01-09 10:23:14
【问题描述】:

我要开门见山了:

//ComponentHolder.h

template<class Holder, uint ID>
class TemplateComponentHolder : public ComponentHolderInterface {
protected:
    std::vector<ComponentType*> mComponents;


public:
   TemplateComponentHolder() : ComponentHolderInterface(ID) {}

   static const uint getStaticID() { return ID; }
};

class ConcereteComponentHolder1 : public TemplateClassHolder<ComponentType, 1000> {
public:
    inline void print() { std::cout << "test"; }
};

//World.h
class World {
private:
   std::map<uint, ComponentHolderInterface*> mHolders;
public:
   template<class Holder> Holder * getHolder() {
       auto i = mHolders.find(Holder::getStaticID());
       if(i != mHolders.end())
          return static_cast<Holder*>((*i));
       return NULL;
   }

   /* ... */
};

//Main code
int main() {
  World * world = new World;
  world->addHolder(new ConcerteComponentHolder1);

  world->getHolder<ConcreteComponentHolder1>()->print();
}

我收到未解决的外部符号错误。说无法解析“ConcereteComponentHolder1::ID”。如果我将静态变量更改为非 const 并将其添加到源文件:

//ComponentHolder.cpp
uint ConcreteComponentHolder1::ID = 1000;

没有问题。为什么必须明确定义后一个是有道理的。但是当我使用const 时,我必须在标题中定义它。使用 const 时出现链接器错误是没有意义的。是因为头文件中生成了模板函数吗?还是别的什么?

【问题讨论】:

  • “当我使用const时,我必须在标题中定义它”。为什么?
  • 我刚刚意识到我可以在定义中使用 const。我只是希望有一种更简单的方法来解决这个问题。就像使用一个静态的getId(),那么我就不需要每次都定义它了。
  • 如果你真的在使用 C++11 是可能的:constexpr uint getId() { return 1; }
  • 不仅没有切中要害,而且在您编辑了代码之后,这个问题就没有意义了。

标签: c++ templates c++11 static


【解决方案1】:

在类声明中放置一个变量声明和一个初始化器实际上并不构成一个定义。只要您只接受它的价值并且从不尝试将其用作参考,您就可以在没有定义的情况下逃脱。

'find' 将值的引用作为参数。这意味着您需要在某处定义一个实际变量来引用它。

您可能还想阅读这个 SO 问题:Defining static const integer members in class definition

【讨论】:

  • 一个问题。我没有使用 ID 作为变量,而是创建了一个 getStaticID() 静态函数,每个子类都定义了它。请检查我编辑的新代码。 getStaticId 按预期工作,但我想知道它是否只是我的编译器正确链接它还是有效代码?派生类可以访问父类的静态函数吗?
  • 因为您使用的是模板函数,其中特定类被参数化,您访问的是派生类的静态方法,而不是父类。还是我误解了你的问题?
  • 顺便说一句,最好不要像那样编辑问题。现在的问题和答案对于其他搜索此类问题的人来说毫无意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 2017-10-06
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 2018-07-12
相关资源
最近更新 更多