【问题标题】:Getting "Multiple definition" with no apparent reason在没有明显原因的情况下获得“多重定义”
【发布时间】:2017-05-10 09:18:02
【问题描述】:

问题从标题就很清楚了。代码如下:

TimeTask.hpp:

#pragma once
#include <locale>
#include <codecvt>
#include <chrono>

namespace TimeTask {

static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;

std::tm * to_date(
    int day, int month, int year,
    int hours = -1, int minutes = -1, int seconds = -1
) {
    time_t rawTime = time(0);
    std::tm * tInfo = localtime(&rawTime);
    tInfo->tm_mday  = day;
    tInfo->tm_mon   = month - 1;
    tInfo->tm_year  = year - 1900;

    if(hours >= 0)
        tInfo -> tm_hour = hours;
    if(seconds >= 0)
        tInfo -> tm_sec = seconds;
    if(minutes >= 0)
        tInfo -> tm_min = minutes;

    return tInfo;
}

std::string from_time_point(const std::chrono::system_clock::time_point &arg) {
    time_t time = std::chrono::system_clock::to_time_t(arg);
    return ctime(&time);
}

}

Task.hpp:

#pragma once

#include <string>
#include "TimeTask.hpp"

class Task
{
public:
    Task(
        const std::basic_string<wchar_t>&,
        const bool&,
        const std::chrono::system_clock::time_point&
    );
    Task();

    std::basic_string<wchar_t>                  description;
    bool                                        executed;
    std::chrono::system_clock::time_point       date;

    std::wstring towString();
};

Task.cpp:

#include "Task.hpp"
#include <sstream>    

Task::Task(
    const std::basic_string<wchar_t>& description,
    const bool& executed,
    const std::chrono::system_clock::time_point& date
):
    description(description),
    executed(executed),
    date(date) { }

Task::Task():
    Task( L"Task", false, std::chrono::system_clock::now() ) { }

std::wstring Task::towString() {
    std::wostringstream retval(L"");

    retval << L"Task:\t"
           << description
           << L"\nPerformed:\t"
           << std::boolalpha << executed;    

    retval << TimeTask::converter.from_bytes(TimeTask::from_time_point(date));

    return retval.str();
}

ma​​in.cpp:

#include    <iostream>
#include    <type_traits>
#include    <vector>
#include    <list>
#include    "Task.hpp"

int main () {
    Task t1(L"Lezione programmazione",
            false,
            std::chrono::system_clock::from_time_t(
                std::mktime(TimeTask::to_date( 5,5,2017)) ));

    Task t2(L"Lezione programmazione",
            false,
            std::chrono::system_clock::from_time_t(
                std::mktime(TimeTask::to_date( 1,10,2017)) ));

    Task t3(L"Lezione programmazione",
            false,
            std::chrono::system_clock::from_time_t(
                std::mktime(TimeTask::to_date( 1,17,2017 )) ));

    std::list   <Task>    agenda1 = { t1, t2, t3 };
    std::vector <Task>    agenda2 = { t1, t2, t3 };

    for( auto it : agenda1 )
        std::cout << TimeTask::converter.to_bytes(it.towString());

    return 0;
}

我在这里做错了什么?我没有看到 to_datefrom_time_point 的任何多重定义(我的编译器正在抱怨的函数是 g++)。

【问题讨论】:

  • 因为TimeTask.hpp包含函数的定义,并且被多个实现文件包含。你应该把声明放在头文件中,把定义放在实现文件中。

标签: c++ multiple-definition-error


【解决方案1】:

您应该将这些函数标记为inline。因为你的头文件不仅声明了,还定义了这个函数。并且当从多个翻译单元中包含时,它们都会编译该函数的一个实例,并且在链接过程中会出现错误。

详见单一定义规则([basic.def.odr]):

  1. 每个程序都应包含一个定义,该定义在该程序中被丢弃的语句之外的 odr 使用的每个非内联函数或变量;无需诊断。 定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 [class.ctor]、[class.dtor] 和 [class.copy ])。 内联函数或变量应在被丢弃语句之外的每个翻译单元中定义。

/../

  1. 类类型、枚举类型、带外部链接的内联函数 ([dcl.inline])、带外部链接的内联变量 ([dcl.inline])、类模板、非静态的定义可以有多个函数模板、类模板的静态数据成员、类模板的成员函数或在程序中未指定某些模板参数([temp.spec]、[temp.class.spec])的模板特化,前提是每个定义出现在不同的翻译单元中,并且定义满足以下要求。

【讨论】:

  • 它有效,但究竟为什么我需要将其指定为内联?
  • 谢谢,我会尽量把这个答案标记为正确的。
  • 如果你不想将函数指定为内联函数,请为函数制作一个单独的源文件,并将它的原型放在标题中。
猜你喜欢
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多