gpt4 book ai didi

c++ - 如何为函数正确创建标题,而没有多个定义错误?

转载 作者:行者123 更新时间:2023-12-03 07:38:07 24 4
gpt4 key购买 nike

我有一个 header ,定义了我需要的一些功能。我将它们包含在两个文件中,它们本身都包含在main.cpp中,但是尽管我放了

#ifndef MYFUNCTION_H
#define MYFUNCTION_H
//code
#endif
在我的代码中。
那我做错了什么?这是我的标题:
#ifndef EXTRASFMLFUNCTIONS_H
#define EXTRASFMLFUNCTIONS_H

#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Text.hpp>

inline void setCenterPos(sf::Sprite &entity, const sf::Vector2f& position)
{
entity.setPosition(sf::Vector2f{(position.x - entity.getGlobalBounds().width / 2), position.y - (entity.getGlobalBounds().height / 2)});
}

inline void setCenterPos(sf::Text &entity, const sf::Vector2f& position)
{
entity.setPosition(sf::Vector2f{(position.x - entity.getGlobalBounds().width / 2), position.y - (entity.getGlobalBounds().height / 2)});
}

inline sf::Vector2f getCenter(const sf::Sprite& entity)
{
return sf::Vector2f{entity.getGlobalBounds().width / 2, entity.getGlobalBounds().height / 2} + entity.getPosition();
}

inline void scaleTo(sf::Sprite& entity, const sf::Vector2f& size)
{
entity.scale(size.x / entity.getGlobalBounds().width, size.y / entity.getGlobalBounds().height);
return;
}

inline void scaleToWidth(sf::Sprite& entity, const float &width)
{
entity.scale(width / entity.getGlobalBounds().width, width / entity.getGlobalBounds().width);
return;
}

inline void scaleToHeight(sf::Sprite& entity, const float &height)
{
entity.scale(height / entity.getGlobalBounds().height, height / entity.getGlobalBounds().height);
return;
}

#endif
编辑:它与内联关键字一起使用

最佳答案

在C++中,一个定义规则(ODR)规定对象和非内联函数在整个程序和模板和类型中最多只能有一个定义(按翻译单元)。正如cppreference在“一个定义规则”下所述:

One and only one definition of every non-inline function or variablethat is odr-used (see below) is required to appear in the entireprogram (including any standard and user-defined libraries). Thecompiler is not required to diagnose this violation, but the behaviorof the program that violates it is undefined.


这就是为什么不内联函数时会收到多个定义链接错误的原因。这些功能包括(字面复制)到实现文件中。 header 防护不会阻止此操作,因为文件是单独包含的。因此您违反了ODR,因为多次定义了具有外部链接的相同功能。
内联函数时,每个翻译单元(实现文件+所有包含文件)都将获得其自己的函数副本。当链接器链接目标文件时,由于 inline关键字,这不会被视为违反ODR。这就是 inline的特殊之处:它告诉链接程序同一个函数的多个定义不是错误。
您有两种选择:
  • 像您一样内联函数;
  • 将函数声明放在头文件中,并将定义放在一个cpp文件中

  • 我会选择第一个选项,因为函数简短而不那么复杂。

    关于c++ - 如何为函数正确创建标题,而没有多个定义错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65460620/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com