c ++ / struct的范围

时间:2015-11-09 10:21:29

标签: c++ scope

在下面的代码中,我认为结构stSameNameButDifferent是本地范围定义,因此没有问题。但我在运行时遇到错误。 (错误:进程崩溃)

你能解释一下这段代码的错误吗?

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 个答案:

答案 0 :(得分:2)

为了避免在多个翻译单元中发生相同struct名称的冲突,您必须将它们放在未命名的名称空间中,如下所示:

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

这会使stSameNameButDifferent仅在相应的翻译单元(.cpp文件)中私下看到。

否则链接器将使用找到的第一个符号解析符号,因此会在运行时看到错误。

答案 1 :(得分:0)

您已在全局范围内定义stSameNameButDifferent,因此编译器无法查看和分析这两个定义到同一struct,并且它只接受它遇到的第一个定义,这就是您收到错误的原因。

您可以为test_atest_b使用两个不同的命名空间,这样您就不会收到任何错误。