0

言語を 1 年以上使用していなかったので、C++ を再び使い始めたばかりなので、しばらくお待ちください。

別のクラスのオブジェクトへの参照を引数として受け取るメソッドを持つクラスがあります。コードは次のようになります: (pastebin の完全なコード)

//Entity.h
namespace xe {    
class Entity {...}
}

//Component.h
#include "entity.h"

class Entity;
namespace xe{
class Component
{
  public : 
  void set_parent(Entity&);
  private :
  Entity* m_parent;
}
}

//Component.cpp
#include "component.h"

xe::Component::set_parent(Entity& entity) { m_parent = &entity;}

//Main.cpp
#include "Entity.h"
#include "Component.h"
int main()
{
  Entity entity(1 /*id*/);
  Component comp;
  comp.set_parent(entity);
}
}

このコードは、次のコンパイル エラーをトリガーします (ビジュアル スタジオ)

error c2664:xe::Component::set_parent(Entity&) : cannot convert parameter 1 from xe::Entity to Entity&

その間、次のコードが実行され、完全に正常にコンパイルされます

void square(int& i)
{
  i *= i;
}
int main()
{
  int number = 2;
  square(number);
  std::cout<<number;
}

私が言ったように、私は C++ の専門家ではありませんが、私にとって 2 つの関数の唯一の違いは、square() がプリミティブ データ型 (int) への参照を受け取るのに対し、do_something() は a のインスタンスへの参照を受け取ることです。クラス。クラスオブジェクトを参照で渡すことについて何も見つけることができず、すでにいくつかの代替手段を試しました(参照 const を作成し、Bar& 型の変数を明示的に作成してそれをメソッドに渡します)が、何も機能しなかったので、ここで質問したいと思いました.

4

1 に答える 1

2

問題はライン

class Entity;

これは、グローバル スコープにクラス Entity があることをコンパイラに伝えます。このクラスは、名前空間内で定義するクラス Entity とは異なります。main() はグローバル名前空間に存在するため、前方宣言を使用します。ただし、ライン

comp.set_parent(entity);

このグローバル スコープ クラスのオブジェクトを名前空間内で定義された関数に渡そうとします。その結果、その名前空間内のクラスのオブジェクトが必要になります。

entityこれを修正するには、前方宣言のある行を削除し、のインスタンス化をに変更する必要があります

xe::Entity entity(1 /*id*/);

編集:コードには他にも多くの名前空間/スコープ関連の問題がありましたが、以下のバージョンはエラーなしでコンパイルされます。C++ でプログラミングするときは、この種のエラー メッセージを読むことを絶対に学ぶ必要があるため、発生した各エラーをよく見て、その位置で行った変更を確認することをお勧めします。

//Entity.h
#pragma once
#include<memory>
#include<list>    //necessary to use std::list

namespace xe {
    class Component;    //must be inside namespace xe

    class Entity {
    public :
        Entity(unsigned int);
        std::list<std::unique_ptr<Component>> m_components;
        void add_component(Component&);
    private :
        unsigned int m_id;
    };
}

//Entity.cpp
#include "Entity.h"

xe::Entity::Entity(unsigned int id) {    //the name needs to reference the constructor _within_ the class, not the class itself
    m_id = id;
}

void xe::Entity::add_component(xe::Component& component) {    //Never forget the return type (unless you are writing a constructor/destructor, which do not have a return type. Also, component was misspelled...
    m_components.push_back(std::unique_ptr<Component>(&component));
}

//Component.h
#pragma once
#include "Entity.h"
//class Entity;   //Unnecessary, it's already defined within Entity.h.
namespace xe {
    class Component {
        public :
            void set_parent(xe::Entity&);

        private :
            xe::Entity* m_parent;
    };
}

//Component.cpp
#include "Component.h"
void xe::Component::set_parent(Entity& parent) {    //Same problem as with the function above.
    m_parent = &parent;
}

//main.cpp
int main() {
    xe::Entity entity(1);    //main is not within the namespace, nor does it use it, so you need the scope resolution operator here.
    xe::Component comp;    //as above
    entity.add_component(comp);
    comp.set_parent(entity);    //No error anymore...
}
于 2013-07-12T18:49:13.107 に答える