【问题标题】:multiple definitions of function in .cpp file.cpp 文件中函数的多个定义
【发布时间】:2012-10-25 23:32:16
【问题描述】:

编辑:

叹息,我觉得自己像个白痴。直到我问了他的问题几个月后,我才正确地向我解释了 c++ 文件包含。请不要评论我的设置到底有多大缺陷,我非常清楚。

我有一个包含许多 .h 和 .cpp 文件的多文件项目。特别是 io_util.h 会产生一系列奇怪的错误。对于包含函数声明但没有实现的 .h 可以完美编译,但是在函数体所在的 .cpp 中,每个函数都会产生以下错误:

   Multiple markers at this line
- first defined here
- multiple definition of 
 `<namespace>::<function name>(<args>)'

文件“io_util.cpp”只包含在项目 CollectionBase.h 中一次。 “io_util.h”仅包含在“io_util.cpp”中

这是两个文件:

.h:

/*
 * io_util.h
 */

#ifndef IO_UTIL_H_
#define IO_UTIL_H_

#include <iostream>
#include <sstream>
#include <string>
#include <cmath>

#define IO_DEBUG(a) cout << #a << '=' << a << '\n'

#define CASE_SEP 32
#define NUM_CHAR_SEP 48

namespace std
{
    void getVar(int&, int);
    
    void getVar(double&, double);
    
    void getVar(unsigned&, unsigned);
    
    int get_num_digits(int);
    
    int get_digit(int, const int, const int);
    
    string value_of(int);
}

#endif /* IO_UTIL_H_ */

.cpp:

/*
 * io_util.cpp
 */
#ifndef IO_H_
#define IO_H_

#include "io_util.h"

namespace std
{

void getVar(int& i, int forbidden = NAN)
{
    string str;

    while(true)
    {
        getline(cin,str);

        if(str.find_first_not_of("-0123456789") != string::npos || !(stringstream(str) >> i))
        {
            cout << "invalid input.\n\n";
        }
        else if(i == forbidden)
        {
            cout << "illegal value.\n\n";
        }
        else
        {
            break;
        }
    }
}

void getVar(double& d, double forbidden = NAN)
{
    string str;

    while(true)
    {
        getline(cin,str);

        if(str.find_first_not_of("-.0123456789eE") != string::npos || !(stringstream(str) >> d))
        {
            cout << "invalid input.\n\n";
        }
        else if(d == forbidden)
        {
            cout << "illegal value.\n\n";
        }
        else
        {
            break;
        }
    }
}

void getVar(unsigned & u, unsigned forbidden = NAN)
{
    string str;

    while(true)
    {
        getline(cin,str);

        if(str.find_first_not_of("0123456789") != string::npos || !(stringstream(str) >> u))
        {
            cout << "invalid input.\n\n";
        }
        else if(u == forbidden)
        {
            cout << "illegal value.\n\n";
        }
        else
        {
            break;
        }
    }
}

int get_num_digits(int i)
{
    if(i < 0)
    {
        i = -i;
    }

    int result = 1;

    while(i > 10)
    {
        i /= 10;
        result++;
    }

    return result;
}

int get_digit(int i, const int num_digits, const int dig)
{
    if(num_digits < dig)
    {
        return 0;
    }

    const int dig_p10 = pow(10.0,num_digits - dig);

    i -= dig_p10 * round(i/dig_p10);

    if (dig < num_digits - 1)
    {
        i = round(i/int(pow(10.0,num_digits - dig - 1)));
    }

    return i;
}

string value_of(int i)
{
    string str;

    if (i < 0)
    {
        str += "-";
        i = -i;
    }

    const int num_dig = get_num_digits(i);

    for(int n = 0; n < num_dig; n++)
    {
        str += char(get_digit(i, num_dig, n) + NUM_CHAR_SEP);
    }

    return str;
}

}

#endif /*IO_H_*/

我在这个网站上查看了许多关于类似现象的问题,但没有一个有帮助。

【问题讨论】:

  • 我能问一下 IO_H 的栅栏在你的 cpp 文件中做了什么吗?此外,您的 .cpp 文件在 getVar() 参数列表中具有默认值。那些不属于那里。它们属于 .h 文件(或者真的需要复习我的标准文档)。后者可能是您的错误的根源,顺便说一句。
  • "文件“io_util.cpp”只包含在项目CollectionBase.h中一次。“io_util.h”只包含在“io_util.cpp”中,io_util.h不应该是包含在 CollectionBase.h 而不是 io_util.cpp?
  • 如果你 #include 来自 .h 文件的 .cpp 文件,这将解释一切。
  • 我的第一个猜测是您在此处未显示的其他文件中有#include "io_util.cpp" 行。套用温斯顿·丘吉尔的话说,“从不,从不,从不,从不 #include .cpp 文件。”

标签: c++ function include declaration


【解决方案1】:

首先,io_util.cpp 应该在要编译的代码文件的source 文件列表中。项目中任何需要其中包含的功能的地方都应该包含 io_util.h,包括 CollectionBase.h。在anything#include .cpp文件(即不允许#include "io_util.cpp")。

其次,您的 io_util.h 头文件在名为 getVar() 的 std 命名空间(这也是一个禁忌)中声明了函数。尾随参数的默认参数值属于那里不在 io_util.cpp 文件中。

解决这两个问题应该会让你走得更远。

【讨论】:

  • 那么让我看看我是否明白这一点:将 .cpp 包含在 .h 的底部,然后将 .h 包含在我的所有其他文件中?
  • @ValekHalfHeart 嗯,没有。您的程序中有多少个 .cpp 文件?在这一点上,我猜是两个。
  • 更多一些,对于一些类,但它们不应该影响这一点。我有一个程序启动的 main.cpp 和 io_util.cpp。
  • @ValekHalfHeart单独编译每个 .cpp 文件。 从不在源文件中使用#include 语句包含 .cpp 文件。你知道如何将多个 .cpp 文件编译成一个最终的可执行文件吗?
  • 显然不是。我总是被教导说 .cpp 和 .h 文件之间没有实际区别,并且使用不同的扩展名只是因为惯例。显然,情况似乎并非如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多