我正在完成第36页使用C ++ 2e 编程原则和练习的练习
我有:
尝试编译时收到以下错误:
g++ d0.cpp d0m.cpp -o d0.o -std=gnu++11
/tmp/name/cc09EWiA.o: In function `chrono::operator<<(std::ostream&, chrono::Month const&)':
d0m.cpp:(.text+0x0): multiple definition of `chrono::operator<<(std::ostream&, chrono::Month const&)'
/tmp/name/ccPAVaW9.o:d0.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
似乎问题是Month.h中的运算符重载
这就是我理解流程包含的方式:
month.h
^
|
|
d0.h<---------d0m.cpp
^
|
|
d0.cpp
我的理解是将枚举和(枚举类?)放在自己的标题中是一种好习惯。通过扩展,在那里包含运算符重载似乎是合乎逻辑的。
正确的方法是在Month.h中定义运算符重载并在Month.cpp中创建定义吗?
// Month.h -> Enum Class used in Date71 class definition in d0.h
#pragma once
#include <string>
#include <iostream>
#include <vector>
namespace chrono
{
enum class Month
{
jan=1,feb,mar,apr,jun,jul,aug,sep,oct,nov,dec
};
const vector<string> month_tbl = {"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"November",
"December"};
extern ostream& operator<<(ostream& os, const Month& m)
{
return os << month_tbl[int(m)];
}
}
#pragma once
#include "../../std_lib_facilities.h"
#include "Month.h"
namespace chrono
{
class Date71
{
public:
Date71(int y, Month m, int d); // check for valid date and initialize
void add_date(int n); // increase Date by n days
Month month();
int day();
int year();
private:
int y; // year
Month m;
int d; // day
};
// d0.cpp
#include "../../std_lib_facilities.h"
#include "d0.h"
namespace chrono
{
Month Date71::month(){return m;}
int Date71::day(){return d;}
int Date71::year(){return y;}
void Date71::add_date(int n)
{
d = (d < 31) ? d+n : d;
}
ostream& operator<<(ostream& os, Date71& b)
{
return os <<'('<<b.year()
<<','<<b.month()
<<','<<b.day()<<')';
}
}
//d0m.cpp
#include "../../std_lib_facilities.h"
#include "d0.h"
using namespace std;
int main(void)
{
chrono::Date71 forth(1978,chrono::Month::jul,25);
chrono::Date71 forthC = forth;
thirdC.add_date(1);
chrono::Date71 forthW(1978,chrono::Month::jul,35);
cout << forth;
cout << forthC;
return 0;
}
答案 0 :(得分:1)
要解决此问题,我将运算符从 Month.h 重载到新文件 Month.cpp 。
在此之后,我得到了一些非常奇怪的错误,关于编译器无法识别像vector
这样的类型。调查进一步显示,../../std_lib_facilities.h
包含 d0.h 已包含许多标准库组件,但也有using namespace std
。
知道这一点后,我用../../std_lib_facilities.h
替换std库头的任何实例,然后编译所有内容。
注意:std_lib_facilities.h
是本书的标题。它试图将读者与图书馆的一些细节及其包含在一般情况下隔离开来。
答案 1 :(得分:1)
多个翻译单元中可能出现的每个功能定义必须至少是以下之一:
inline
(如果定义位于class
正文中,或者如果constexpr
具有static
),则表示这意味着namespace
template
extern template
(有一些涉及rowText = "mary have a little lamb"
的注意事项)