2015-11-09 145 views
0

在下面的代碼中,我認爲結構stSameNameButDifferent是本地作用域定義,所以它沒有問題。但是我在運行時遇到錯誤。 (錯誤:進程崩潰)C++ /範圍結構

你能解釋一下什麼是錯的代碼?

test_function.h

#ifndef TEST_FUNC_H_ 
#define TEST_FUNC_H_ 
void test_a(); 
void test_b(); 

#endif 

的main.cpp

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

using namespace std; 

int main(int argc, const char** argv) 
{ 
     cout << "testing for struct scope" << endl; 
     test_a(); 
     test_b(); 
     return 0; 
} 

test_a.cpp

#include <iostream> 
#include <sstream> 
#include <cstdint> 
#include <list> 
#include "test_function.h" 

struct stSameNameButDifferent 
{ 
     uint32_t nPlayCode; 
     uint32_t nGameID; 
     std::string sGameName; 
}; 

void test_a() 
{ 
     std::list<stSameNameButDifferent> lstSt; 
     for(int i=0; i<10; ++i) 
     { 
       stSameNameButDifferent st; 
       st.nPlayCode = i; 
       st.nGameID = 100+i; 
       std::ostringstream osBuf; 
       osBuf << "Game_" << i; 
       st.sGameName = osBuf.str(); 
       lstSt.push_back(st); 
     } 
     for(auto &st : lstSt) 
     { 
       std::cout << st.nPlayCode << ", " << st.nGameID << ", " << st.sGameName << std::endl; 
     } 
} 

test_b.cpp

#include <iostream> 
#include <sstream> 
#include <cstdint> 
#include <list> 
#include "test_function.h" 

struct stSameNameButDifferent 
{ 
     uint32_t nPlayCode; 
     uint32_t nGameID; 
     float fDiscountRate; 
     std::string sGameName; 
}; 

void test_b() 
{ 
     std::list<stSameNameButDifferent> lstSt; 
     for(int i=0; i<10; ++i) 
     { 
       stSameNameButDifferent st; 
       st.nPlayCode = i; 
       st.nGameID = 1000+i; 
       st.fDiscountRate = (float)i/100; 
       std::ostringstream osBuf; 
       osBuf << "Game_" << i; 
       st.sGameName = osBuf.str(); 
       lstSt.push_back(st); 
     } 
     for(auto &st : lstSt) 
     { 
       std::cout << st.nPlayCode << ", " << st.nGameID << ", " << st.sGameName << std::endl; 
     } 
} 
+2

恭喜,你見過你的第一個不平凡的大小的程序,現在你知道爲什麼你不應該使用'使用命名空間std;'和希望定義自己的命名空間。 – Surt

+1

_「我得到了錯誤」_有什麼錯誤? –

+0

@Surt:這與'使用命名空間std'無關。 –

回答

2

間在多個翻譯單位相同struct名爲了避免發生衝突,你必須把它們放在一個未命名的命名空間中,像這樣:

namespace { 
    struct stSameNameButDifferent { 
     uint32_t nPlayCode; 
     uint32_t nGameID; 
     std::string sGameName; 
    }; 
} 

這將使stSameNameButDifferent只在相應的翻譯單元(.cpp文件)看到私人。

否則,鏈接器將會找到找到的第一個符號,因此會在運行時看到錯誤。

0

已在全球範圍內定義stSameNameButDifferent,所以編譯器看不到了兩個定義分析以相同struct,而且只取第一個它滿足,這就是爲什麼你得到一個錯誤。

對於test_atest_b,可以使用兩個不同的命名空間,所以不會出現任何錯誤。

+0

_「編譯器可以看到兩個定義到相同的結構」_你錯了。 –

+0

@LightnessRacesinOrbit,謝謝。修復。 – ANjaNA