質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

614閲覧

LNKエラー (2005)(1169)

TETNZ

総合スコア1

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/05/29 23:16

初めまして。現在C++を動画を見ながら練習しています。
現在SFMLライブラリーを使った簡単なゲームのプログラムを組んでいますが(VS2022 )、リンクエラーがでて困っています。
例として(gameWorld.h),(gameWorld.cpp)(main.cpp)三つのコードおよびエラーコードを表示しています。他のファイル例えば(enemy.cpp,enemy.h)などの他のファイルでも同様の症状があります。

当方の認識では外部ファイルへのリンクは#include "ファイル名"を行う事で可能と認識しています。その認識に沿った形で参考にしている動画内でmain.cppではgameWorld.cppを、そしてgameWorld.cppではgameWorld.hをインクルードしています。
ただし下記のコードをVS2022でコンパイルするとエラーがでます。
色々試しているうちにmain.cppないのインクルードをgameWorld.cppではなくてgameWorld.hにするとコンパイルがエラーなしで成功することにきづきました。

そこで質問なのですが、main.cppのインクルードをCPPからHに変更することでエラーがなくなるのは正しい挙動なのでしょうか?(私の認識ではこの変化でgameWorld.cppへのリンクが切れているよう気がするのですが。。。)
初歩的な質問かもしれませんが、どうぞご教授ください。
よろしくお願いします

gameworld.h

1#include <SFML/Graphics.hpp> 2#include <SFML/Audio.hpp> 3#include <iostream> 4#include <string> 5using namespace std; 6 7#ifndef GAMEWORLD_H 8#define GAMEWORLD_H 9 10class GameWorld 11{ 12private: 13 bool isGameOver; 14 int damage; 15 sf::Texture backgroundTexture; 16 sf::Sprite background; 17 sf::Time time; 18 bool loadBackground(); 19public: 20 bool performSetup(); 21 bool runGame(); 22 GameWorld(); 23 24}; 25#endif

gameWorld.cpp

1#include "gameWorld.h" 2 3GameWorld::GameWorld() { 4 damage = 10; 5}; 6 7bool GameWorld::loadBackground() { 8 if (!backgroundTexture.loadFromFile("assets/background.png")) { 9 std::cout << "Could not load background image" << std::endl; 10 return false; 11 } 12 background.setTexture(backgroundTexture); 13 background.scale(sf::Vector2f(1.6, 2.25)); 14 return true; 15}; 16 17 18bool GameWorld::performSetup() { 19 isGameOver = false; 20 return loadBackground(); 21}; 22 23 24bool GameWorld::runGame() 25{ 26 sf::RenderWindow window(sf::VideoMode(1000, 1000), "Point and Click Game"); 27 sf::Clock clock; 28 while (window.isOpen()) 29 { 30 sf::Event event; 31 while (window.pollEvent(event)) 32 { 33 if (event.type == sf::Event::Closed) { 34 window.close(); 35 return false; 36 } 37 } 38 window.clear(); 39 window.draw(background); 40 window.display(); 41 } 42 return false; 43};

main.cpp

1#include "gameWorld.cpp" 2 3int main() 4{ 5 6 GameWorld world = GameWorld(); 7 while (true) { 8 GameWorld world = GameWorld(); 9 if (!world.performSetup()) { 10 return 1; 11 } 12 if (!world.runGame()) { 13 return 0; 14 } 15 } 16 17 return 0; 18}; 19
Severity Code Description Project File Line Suppression State Warning C26495 Variable 'GameWorld::isGameOver' is uninitialized. Always initialize a member variable (type.6). SFML_New (ファイルパス)-with Audio\game.cpp 4 Warning C4305 'argument': truncation from 'double' to 'T' SFML_New (ファイルパス) -with Audio\game.cpp 14 Warning C4305 'argument': truncation from 'double' to 'T' SFML_New (ファイルパス) -with Audio\game.cpp 14 ーーーーーーー問題のエラーー----------- Error LNK1169 one or more multiply defined symbols found SFML_New (ファイルパス) -with Audio\Debug\SFML_New.exe 1 Error LNK2005 "public: __thiscall GameWorld::GameWorld(void)" (??0GameWorld@@QAE@XZ) already defined in game.obj SFML_New (ファイルへのパス)\SFML Working\SFML_New -with Audio\source.obj 1 Error LNK2005 "public: bool __thiscall GameWorld::runGame(void)" (?runGame@GameWorld@@QAE_NXZ) already defined in game.obj SFML_New (ファイルパス)-with Audio\source.obj 1 Error LNK2005 "public: bool __thiscall GameWorld::performSetup(void)" (?performSetup@GameWorld@@QAE_NXZ) already defined in game.obj SFML_New (ファイルパス) -with Audio\source.obj 1 Error LNK2005 "private: bool __thiscall GameWorld::loadBackground(void)" (?loadBackground@GameWorld@@AAE_NXZ) already defined in game.obj SFML_New (ファイルパス) -with Audio\source.obj 1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

インクルードとリンクの区別が曖昧になっているように感じます。

インクルルード:単に、テキストをその部分に挿入するだけ
リンク:オブジェクトを結合する

提示されたエラーは、複数回定義されているというものです。
CPPの中で定義しており、それを複数ヶ所でインクルードすると当然、複数ヶ所での定義となります。

なお、言語処理系でリンクと言うと、普通はコンパイル済みのファイルを結合することを言います。
なので、「gameWorld.cppへのリンクが切れている」という言い方はちょっと不自然です。
言うなら、「定義ではなく、参照になった」でしょう。

ひょっとすると、定義と宣言の区別も曖昧になっているかも知れません。

投稿2022/05/30 01:50

nob.

総合スコア711

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

はい。 通常は include するのはヘッダです。 リンクの関係をソースコード上に書くことは通常はありません。 (処理系の拡張として出来るようになっているものもあります。) リンクはプロジェクトファイルなど、言語の外で管理します。

C++ では各翻訳単位 (一般に *.cpp ファイルひとつが翻訳単位) ごとにコンパイルしてからリンクするのですが、他の翻訳単位にどんなものがあるのかわからないとそれを使えないのでどんなものがあるのかだけわかるようにヘッダ (クラス定義や宣言が書かれている) を通じて知るような仕組みです。

投稿2022/05/29 23:47

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問