正在将助手函数移动到头文件

Moving helper function to header file

本文关键字:移动 文件 函数      更新时间:2023-10-16

一开始我有:

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

某些.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.cppsomething.cpp中,所以存在重复的符号,对吧?

问题,有没有可能懒洋洋地把所有的东西都放在标题里?或者没有办法,必须分开贴花和定义?我不在乎(在这种情况下(将实现隐藏在.cpp中,我只想将它从sth中移出。

也许可以将print_me的定义向下移动到util.cpp,并只在util.h文件中留下它的声明。

否则,在每个对象文件中都会得到它的副本,然后链接器会被混淆,因为它们都有相同的名称(符号(。