【问题标题】:C plus plus about defining static data member in header file or source fileC plus plus关于在头文件或源文件中定义静态数据成员
【发布时间】:2013-11-05 11:00:29
【问题描述】:

我在 B.h 头文件中定义了一个 B 类。 B 有一个静态数据成员。我在头文件的 B 类中定义了这个静态数据成员。但是当我构建它时,会发生错误。

  1. main.obj:错误 LNK2005:“公共:静态类 std::basic_string,类 标准::分配器 > B::b" (?b@B@@2V?$basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@A) 已经在 B.obj 中定义

  2. 致命错误 LNK1169:找到一个或多个多重定义符号

B.h:

#ifndef _B_H
#define _B_H
#include <string> 
class B
{
public:
  B();
  ~B();
  static void showfunc();
  static std::string b;
};
std::string B::b = "BBB";
#endif

B.cpp:

#include <iostream>
#include <string>
#include "B.h"

using namespace std;

B::B()
{

}
B::~B()
{

}
void B::showfunc()
{
  cout<<b<<endl;
}

// main.cpp
#include <iostream>
#include "B.h"
using namespace std;

int main()
{
  B b_obj;  
  b_obj.showfunc();
  return 0;
}

【问题讨论】:

  • 这不是问题,但是以下划线开头后跟大写字母 (_B_H) 的名称和包含两个连续下划线的名称保留供实现使用。不要使用它们。

标签: c++


【解决方案1】:

您在头文件中定义了一个静态变量。仅当静态文件仅包含一次时才有效!但是您将它包含了两次(main.cpp 和 B.cpp)。 将以下行移至 B.cpp 即可:

std::string B::b = "BBB";

【讨论】:

  • 对不起,我不能,上面的人也给出了正确的答案。也许下次:)
【解决方案2】:

您需要将b 的定义移动到.cpp 文件中。

【讨论】:

    【解决方案3】:

    我在头文件的 B 类中定义了这个静态数据成员。但是当我构建它时,就会发生错误。

    那就别那么做了!

    不要在标题中定义静态成员。您将在 #includes 标头的每个 TU 中引入定义。

    改为在一个 TU中定义它们;最简单的方法是在 .cpp 文件中。

    【讨论】:

      【解决方案4】:
      // B.h 
      #ifndef _B_H
      #define _B_H
      #include <string> 
      class B {
      public:
         B();
         ~B();
         static void showfunc();
         static std::string b;
      };
      #endif
      
      //B.cpp #include <iostream> 
      #include <string>
      #include "MyHeader1.h"
      using namespace std; 
      B::B(){} 
      B::~B(){}
      
      void B::showfunc(){
         cout<<b<<endl;
      }
      
      // main.cpp 
      #include <iostream> 
      #include "MyHeader1.h" 
      using namespace std; 
      std::string B::b = "BBB"; 
      
      int main(){
         B b_obj;    
         b_obj.showfunc();
         return 0; 
      }
      

      这里是你的解决方案

      【讨论】:

        【解决方案5】:

        如果您在 hader 文件中编写定义,则此定义将在包含此标头的每个对象模块中复制。所以链接器将不知道使用哪个定义以及这些定义是否等效。

        【讨论】:

        • 我明白了。谢谢。我将它的定义移到我的源文件中。
        猜你喜欢
        • 2019-12-26
        • 2011-06-06
        • 1970-01-01
        • 2013-11-16
        • 2011-08-24
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多