C++ Множественное определение вспомогательной функции

РЕДАКТИРОВАТЬ: ответил - проблема была в том, что, поскольку функции имели одну и ту же сигнатуру, несмотря на то, что они были в отдельных файлах, C++ видел обе версии и запутался.

У меня есть три класса: Table а также Bed оба наследуют от Furniture,

Table а также Bed у каждого есть вспомогательная функция GetLowerCase(std::string) определяется в каждом классе индивидуально. когда make запущен (Makefile показан ниже), я получаю сообщение об ошибке, что GetLowerCase в Bed.cpp был впервые определен в Table.cpp

Makefile:

main: main.o Furniture.o Table.o Bed.o
        g++ main.o Furniture.o Table.o Bed.o -o main

main.o: main.cpp
        g++ -c main.cpp

Furniture.o: Furniture.cpp Furniture.h
        g++ -c Furniture.cpp

Table.o: Furniture.cpp Table.cpp Table.h
        g++ -c Table.cpp

Bed.o: Furniture.cpp Bed.cpp Bed.h
        g++ -c Bed.cpp

clean:
        rm *.o main

Table.cpp:

#include "Table.h"
#include <iostream>
#include <string>

std::string GetLowerCase(std::string str)
{
        std::string out;
        for (int i=0; i<str.length(); i++)
        {
                out[i] = tolower(str[i]);
        }
        return out;
}

Table::Table(const std::string n, std::string wt) : Furniture(n)
{
        wood_type = GetLowerCase(wt);
        if (wood_type != "pine" && wood_type != "oak")
        {
                std::cerr << "Wood type must be OAK or PINE.";
        }
}

void Table::Print()
{
        Furniture::Print();
        std::cout << "Wood Type: " << wood_type << std::endl;
}

Bed.cpp:

#include "Bed.h"
#include <iostream>
#include <string>

std::string GetLowerCase(std::string str)
{
        std::string out;
        for (int i=0; i<str.length(); i++)
        {
                out[i] = tolower(str[i]);
        }
        return out;
}

Bed::Bed(const std::string n, std::string sz) : Furniture(n)
{
        size = GetLowerCase(sz);
        if (size != "twin" && size != "full" && size != "queen" && size != "king")
        {
                std::cerr << "Bed size must be TWIN, FULL, QUEEN, or KING.";
        }
}

void Bed::Print()
{
        Furniture::Print();
        std::cout << "Size: " << size << std::endl;
}

Я бы подумал что GetLowerCase будет полностью содержаться в .cpp файл, в котором он был определен и не будет "виден" другими файлами.

Его нет ни в каких заголовочных или исходных файлах, кроме двух перечисленных выше. Очень смущен, и хотел бы помочь!

2 ответа

Либо объявите свою функцию static или обернуть его в анонимное пространство имен:

namespace {
    // duplicated names here.
}

Ваши варианты:

  1. Переместите все свои вспомогательные функции в вспомогательный класс (например, CommomUtils) как static функции-члены. Я рекомендую этот способ, это больше C++, и вы можете избежать дублирования кода.

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

  3. Деформируйте свою функцию с помощью пространства имен.

  4. Определяет вашу функцию только один раз, и в файле, который вы хотите использовать, используйте extern std::string GetLowerCase(std::string str) чтобы объявить это, тогда вы можете позвонить.

Другие вопросы по тегам