标头保护文件中结构的重复符号

时间:2018-08-11 00:13:47

标签: c++

我遇到了c ++链接问题。我正在尝试为要使用的所有其他文件定义一个Point2D结构。在这里。

#ifndef Point2D_h
#define Point2D_h

#include <iostream>

struct Point2D {
    float x;
    float y;


    Point2D(float x, float y) : x(x), y(y) {}

    Point2D() : x(0), y(0) {}

    Point2D operator+(const Point2D& a) const {
        return Point2D(a.x + x, a.y + y);
    }

    ….
};

std::ostream& operator<<(std::ostream& os, const Point2D& m) {
    return os << "(" << m.x << ", " << m.y << ")";
}

#endif /* Point2D_h */

唯一的问题是,当我尝试构建时,出现重复的符号Point2D错误。我不确定Point2D为什么会是重复的符号,因为它受到标头保护

这里是我所有其他文件,无论它们是否受标头保护以及是否使用Point2D以及它们的导入:

Global.h(头部保护)

#include <stdio.h>
#define MAX 9000

引擎核心(头部保护)

#import "Global.h"
#import "Tests/EngineTests.hpp"
#import "Engine/Engine.hpp"
#import "Particle/Particle.hpp"

Tests.cpp(使用Point2D)

#include "EngineTests.hpp"
#include <iostream>
#include "../Engine/Engine.hpp"

Tests.h

#include "Global.h"

Engine.cpp

#include "Engine.hpp"
#include <iostream>

Engine.hpp(保留标题)

#include "Global.h"
#include "../Particle/ParticleManager.hpp"

Particle.cpp

#include "Particle.hpp"
#include <iostream>

Particle.h(保护标题,使用Point2D)

#include "Global.h"
#include "../Math/Point.h"

ParticleManager.cpp

#include "ParticleManager.hpp"
#include <iostream>

ParticleManager.h(保护标题)

#include <stdio.h>
#include "Global.h"
#include "Particle.hpp"

链接器显示以下内容

duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK7Point2D in:
    …/arm64/Particle.o
    …larm64/Engine.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK7Point2D in:
    …/Particle.o
    …/arm64/EngineTests.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK7Point2D in:
    …/arm64/Particle.o
    …/ParticleManager.o
ld: 3 duplicate symbols for architecture arm64

1 个答案:

答案 0 :(得分:2)

短期解决方案:将inline关键字用于头文件中定义的功能

inline Point2D operator+(const Point2D& a) const {
    return Point2D(a.x + x, a.y + y);
}

inline std::ostream& operator<<(std::ostream& os, const Point2D& m) {
    return os << "(" << m.x << ", " << m.y << ")";
}

长期:除非可衡量的性能下降,否则不要内联任何代码。 (我的团队禁止头文件中的代码)。头文件如下:

#ifndef Point2D_h
#define Point2D_h

#include <iostream>
struct Point2D {
    float x;
    float y;

    Point2D(float x, float y);    
    Point2D();

    Point2D operator+(const Point2D& a) const;

    ….
};

std::ostream& operator<<(std::ostream& os, const Point2D& m);

以及相应的Point2d.cpp文件:

Point2D::Point2D(float x, float y) : x(x), y(y) {}

Point2D::Point2D() : x(0), y(0) {}

Point2D::Point2D operator+(const Point2D& a) const {
    return Point2D(a.x + x, a.y + y);
}

std::ostream& operator<<(std::ostream& os, const Point2D& m) {
    return os << "(" << m.x << ", " << m.y << ")";
}