C 加关于在头文件或源文件中定义静态数据成员

C plus plus about defining static data member in header file or source file

本文关键字:源文件 定义 静态 数据成员 文件      更新时间:2023-10-16

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

  1. main.obj : 错误 LNK2005: "公共: 静态类 标准::basic_string,类 std::分配器> 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;
}

您已在头文件中定义了一个静态变量。仅当静态文件只包含一次时,这才有效!但是您包含它两次(主要.cpp和 B.cpp)。将以下行移动到 B.cpp它就可以工作了:

std::string B::b = "BBB";
您需要

b的定义移动到.cpp文件中。

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

那就干脆不要那样做!

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

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

// 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; 
}

这里是您的解决方案

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