首页 > 解决方案 > 标头保护文件中结构的重复符号

问题描述

我有一个 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"

测试.h

#include "Global.h"

引擎.cpp

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

Engine.hpp(标头保护)

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

粒子.cpp

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

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

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

粒子管理器.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

标签: c++

解决方案


短期解决方案:对头文件中定义的函数使用 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 << ")";
}

推荐阅读