C++辅助函数的多重定义

Posted

技术标签:

【中文标题】C++辅助函数的多重定义【英文标题】:C++ Multiple definition of helper function 【发布时间】:2017-02-09 01:37:05 【问题描述】:

编辑:已回答——问题是因为函数具有相同的签名,尽管它们位于不同的文件中,C++ 看到这两个版本并感到困惑。

我有三个类:TableBed 都继承自 Furniture

TableBed 每个都有一个辅助函数 GetLowerCase(std::string) 在每个类中单独定义。当make 运行时(Makefile 如下所示),我收到一条错误消息,指出Bed.cpp 中的GetLowerCase 最初是在Table.cpp 中定义的

生成文件:

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

表.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;

床.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 文件中,不会被任何其他文件“看到”。

除了上面列出的两个之外,它不在任何头文件或源文件中。很困惑,希望得到一些帮助!

【问题讨论】:

在整个程序中只能有一个具有特定签名的函数,这样做是为了可以在一个文件中定义函数并在另一个文件中使用。如果您不希望某些功能在特定文件之外可见,请参阅 Crazy Eddie 的回答。如果你愿意,那么应该没有其他具有相同签名的函数,从外部也可以看到。 关于makefile:你的目标文件不应该依赖于其他目标文件。目标文件取决于获取该目标文件所需的内容,即源文件和头文件;编译器在链接阶段之前不会查看其他目标文件。 顺便说一句,我看到你的帮助函数在两个文件中是相同的。我建议将其移至带有 util.h 标头的单独 util.cpp 单元。 @yeputons 谢谢,我解决了这个问题。现在在 Makefile 上工作!编辑了问题以反映我现在的情况,但我仍然遇到问题。 我建议避免编辑问题,因为它现在完全不同了。第二个问题是您不应该将-c 密钥传递给gcc 用于链接阶段,-c 表示“仅编译”。 【参考方案1】:

要么声明您的函数static,要么将其包装在匿名命名空间中:

namespace 
    // duplicated names here.

【讨论】:

【参考方案2】:

您的选择:

    将所有辅助函数作为static 成员函数移动到辅助类(如CommomUtils)中。我推荐这种方式,它更C++,并且可以避免重复代码。

    将您的函数声明为static。所以它的范围将在定义它的文件中,而不是全局的。

    使用命名空间扭曲你的函数。

    你的函数只定义一次,在你想使用它的文件中,用extern std::string GetLowerCase(std::string str)声明它,然后你就可以调用它了。

【讨论】:

以上是关于C++辅助函数的多重定义的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的 SetWindowTextW() 辅助函数

C++ STL应用与实现17: 如何使用迭代器辅助函数

如何将测试夹具传递给 C++ GTest 中的辅助函数

辅助函数未加载 laravel 5 - 调用未定义函数

在 Codeigniter 中调用扩展辅助函数时未定义的函数

@Helper辅助方法和@functons自定义函数