0

在一年多没有使用 C++ 之后,我才刚刚开始重新接触 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);
}
}

此代码触发以下编译错误(Visual Studio)

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++ 专家,但对我来说,这两个函数之间的唯一区别是 square() 引用原始数据类型 (int) 而 do_something() 引用一个实例班级。我找不到有关通过引用传递类对象的任何信息,并且我已经尝试了几种替代方法(使引用 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 回答