一开始我有:
main.cpp
#include "something.h"
#include "util.h"
int main() {
sth::something();
utl::little_thing();
}
somehing.h
#ifndef SOMETHING_H
#define SOMETHING_H
namespace sth {
void something();
}
#endif
somehing.cpp
#include "something.h"
#include <string>
#include <iostream>
namespace sth {
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
void something() {
std::cout << "this is something" << std::endl;
print_me("optional");
}
}
util.h
#ifndef UTIL_H
#define UTIL_H
namespace utl {
void little_thing();
}
#endif
util.cpp
#include "util.h"
#include <iostream>
#include <string>
namespace utl {
void little_thing() {
std::cout << "this is little thing" << std::endl;
}
}
然后我将print_me(std::string txt)
从sth
命名空间中删除会更好。然后放在utl
上,在.h文件上声明,在.cpp文件上定义。
那时我懒惰的一面说-最好像以前一样将所有文件都保存在一个文件中。我尝试过:
util.h
#ifndef UTIL_H
#define UTIL_H
#include <string>
#include <iostream>
namespace utl {
void little_thing();
void print_me(std::string txt) {
std::cout << txt << std::endl;
}
}
#endif
something.cpp
#include "something.h"
#include "util.h"
#include <string>
#include <iostream>
namespace sth {
void something() {
std::cout << "this is something" << std::endl;
utl::print_me("optional");
}
}
所以我得到了
c++ -std=gnu++14 -g -Wall -O3 -c -o main.o main.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o util.o util.cpp
c++ -std=gnu++14 -g -Wall -O3 -c -o something.o something.cpp
c++ main.o util.o something.o -o main
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
util.o
duplicate symbol __ZN3utl8print_meENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE in:
main.o
something.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
在我看来,util.h
和main.cpp
中包含something.cpp
,所以有重复的符号,对吗?
问题,是否有可能懒惰地将其全部包含在标题中?还是没有办法,必须将比例和定义分开?我不在乎(在这种情况下)将实现隐藏在.cpp中,我只想将其移出sth
。
答案 0 :(得分:-1)
也许将print_me
的定义下移到util.cpp
,而只在util.h
文件中声明它。
否则,在每个目标文件中都会得到一个副本,然后链接器会因为它们都具有相同的名称(符号)而感到困惑。