C++的头文件与源代码

Author Avatar
Tianqi Zhang 10月 30, 2018

写代码时遇到的一个问题

我把一些常用的函数的定义直接写在了common.h这一个头文件中

#ifndef CPPGOMOKU_COMMON_H
#define CPPGOMOKU_COMMON_H

#include <vector>
#include <cstdio>
#include <string>

namespace gomoku
{
    template<typename T> 
    std::vector<T> range(T begin, T end) {
        std::vector<T> range_vec(end-begin, begin);
        int len = range_vec.size();

        for(int i=1; i<len; ++i) {
            range_vec[i] = begin + i;
        }

        return range_vec;
    }

    void print_center(char *buffer, std::string str, int width) {
        int pos = (width-1) / 2;
        sprintf(buffer, "%%%dc%s%%%dc", pos, str.c_str(), width-1-pos);
        printf(buffer, ' ', ' ');
    }
    void print_center(char *buffer, char *str, int width) {
        int pos = (width-1) / 2;
        sprintf(buffer, "%%%dc%s%%%dc", pos, str, width-1-pos);
        printf(buffer, ' ', ' ');
    }
    void print_center(char *buffer, char character, int width) {
        int pos = (width-1) / 2;
        sprintf(buffer, "%%%dc%c%%%dc", pos, character, width-1-pos);
        printf(buffer, ' ', ' ');
    }
} // end of namespace gomoku

#endif // CPPGOMOKU_COMMON_H

在编译的时候,有两个以上的编译单元都include了这个头文件,导致了多次定义报错。这是因为三个print_center函数没有加inline,编译器在预处理的时候总是会把#include无脑展开,而分别编译意味着各个编译单元彼此看不见对方的CPPGOMOKU_COMMON_H宏是否已经定义。

Reference

Headers and Includes: Why and How