Использование пространства имен для создания глобальных функций, но ошибка в получении нескольких символов - PullRequest
5 голосов
/ 06 августа 2011

Эти функции относятся к типу утилит, которые будут использовать большинство объектов моих программ. Я хочу, чтобы они были в пространстве имен и были глобальными. Это пространство имен определяется в заголовке, а затем добавляется в мой предварительно скомпилированный заголовок. Однако до сих пор я использовал функцию из этого пространства имен в 2 различных объектах, и компилятор выдает ошибку определения нескольких символов для этих 2 объектов.

файл пространства имен

#ifndef UTILS_H
#define UTILS_H

#include <random>
#include <cmath>


namespace Utils
{
    extern int GetRandomBetween(int low, int high)
    {
        if (low < 0 || low >= high)
            return 0;
        int seed = high - low;

        return (rand() % seed) + low;
    }
};

#endif

и мой заголовок precomp

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

//#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <random>


#define SAFE_DELETE( p )       { if( p ) { delete ( p );     ( p ) = NULL; } }
#define SAFE_DELETE_ARRAY( p ) { if( p ) { delete[] ( p );   ( p ) = NULL; } }
#define SAFE_RELEASE( p )      { if( p ) { ( p )->Release(); ( p ) = NULL; } }
// TODO: reference additional headers your program requires here

#include "Utils.h"
#include "Manager.h" // this object uses utils
#include "Bot.h"    // this object uses utils
#include "LinkedList.h"
#include "Village.h"  // this object will use utils in the future

Сообщение об ошибке компоновщика:

Manager.obj : error LNK2005: "int __cdecl Utils::GetRandomBetween(int,int)" (?GetRandomBetween@Utils@@YAHHH@Z) already defined in Bot.obj stdafx.obj : error LNK2005: "int __cdecl Utils::GetRandomBetween(int,int)" (?GetRandomBetween@Utils@@YAHHH@Z) already defined in Bot.obj c:\users\lee\documents\visual studio 2010\Projects\AI\Debug\AI.exe : fatal error LNK1169: one or more multiply defined symbols found

также, возможно, стоит отметить, что в моем заголовке класса Manager я пересылаю объявленного Bot. То же самое с заголовком класса Village.

Ответы [ 2 ]

10 голосов
/ 06 августа 2011

Ваше определение функции (т.е. исходный код) не должно быть в заголовке. Причина, по которой вы получаете несколько определений, заключается в том, что extern не может преобразовать определение функции (исходный код) в объявление функции (т. Е. Просто прототип). Так что вам нужно сделать это:

util.h:

namespace Utils
{
    int GetRandomBetween(int low, int high);
};

SomeSourceFile.cpp (возможно, Util.cpp):

namespace Utils
{
    int GetRandomBetween(int low, int high);
    {
        if (low < 0 || low >= high)
            return 0;
        int seed = high - low;

        return (rand() % seed) + low;
    }
};

Кроме того, вы можете объявить функцию inline в заголовке:

namespace Utils
{
    inline int GetRandomBetween(int low, int high)
    {
        if (low < 0 || low >= high)
            return 0;
        int seed = high - low;

        return (rand() % seed) + low;
    }
};

Хотя вы должны использовать это только для небольших функций.

2 голосов
/ 06 августа 2011

Manager.cpp и Bot.cpp оба включают Util.h

Из-за этого при компиляции оба объектных файла экспортируют символ «GetRandomBetween». Когда компоновщик собирается объединить эти объектные файлы в исполняемый файл, он находит 2 экземпляра функции. Компоновщик не может определить, какой из них использовать (и он не понимает, что они идентичны).

Если вы хотите, чтобы объектные файлы НЕ экспортировали символ (чтобы у вас не было конфликта компоновщика), удалите ключевое слово extern.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...