在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/C++  Linux  網(wǎng)絡安全/ g++ 鏈接 變量被多次定義?

g++ 鏈接 變量被多次定義?

這是map_test.h文件

#ifndef _MAP_TEST_H
#define _MAP_TEST_H

#include <map>
#include <string>

using std::map;
using std::string;

map<string, string> map_config;

void init_map_config();

#endif

這是map_test.cpp文件

#include "map_test.h"

void init_map_config()
{
    map_config.insert({"123", "123"});
    map_config.insert({"456", "456"});
    map_config.insert({"789", "789"});
}

這是main.cpp文件

#include <iostream>
#include "map_test.h"

using std::cout;
using std::endl;

int main()
{
    init_map_config();

    for (auto it = map_config.begin(); it != map_config.end(); it++)
        cout << it->first << " " << it->second << endl;
    cout << endl;
}

編譯:
g++ -c map_test.cpp -o map.o -std=c++11
g++ -c main.cpp -o main.o -std=c++11
編譯都是成功的,鏈接過程出錯:
g++ map.o main.o -o main
此時出錯:

main_test.o:(.bss+0x0): `map_config'被多次定義
map_test.o:(.bss+0x0):第一次在此定義
collect2: error: ld returned 1 exit status

為什么會報錯?

回答
編輯回答
魚梓

1,在map_test.cpp文件中定義map<string, string> map_config;
2,在map_test.h中使用extern map<string, string> map_config;

2018年6月21日 11:47
編輯回答
黑與白

變量和函數(shù)的定義 , 都應該放在cpp文件中, 否則很容易產(chǎn)生多重定義.
為什么呢?
因為c++的編譯單位是cpp文件. 如果這個頭文件被多個cpp包含了, 那么這個頭文件中的定義的變量或者 函數(shù)就會在這些cpp生成的obj中存在, 在鏈接的時候, 就會發(fā)現(xiàn)多個obj存在同一個變量或者函數(shù)實現(xiàn), 自然就會報重定義了.

所以:
除非你能清楚的知道, 這個頭文件只會被一個cpp文件包含一次. 那么放到頭文件中沒有問題.
如果不確定, 那么變量定義或者函數(shù)的實現(xiàn), 就老實的放到.cpp文件中吧.

可能你要問, 變量放到.cpp中的, 那么其它文件中如何使用它呢?
答案是使用聲明: extern
比如: extern map<string, string> map_config;

2017年5月27日 05:33
編輯回答
傻叼

因為違背了ODR。map_config定義在頭文件中,并且是外部鏈接。這個頭文件分別被兩個源文件包含,這導致鏈接時map_config在兩個目標文件中有定義。

解決方案是將定義移到源文件中,在頭文件中只留下純聲明。

2017年8月26日 15:16
編輯回答
凹凸曼

有兩種解決辦法

  1. 在頭文件中使用extern聲明,在源文件中定義

  2. 將map<string, string> map_config和函數(shù)init_map_config都定義為static

2018年9月23日 14:56