通过引用传递类对象

时间:2013-07-12 18:14:00

标签: c++ reference

我刚刚开始使用该语言超过一年后再次进入C ++,所以请耐心等待。

我有一个带有方法的类,该方法将对不同类的对象的引用作为参数。代码几乎看起来像这样:(full code on 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&amp;类型的变量并将其传递给方法)但没有任何效果,所以我想我会问这里。

1 个答案:

答案 0 :(得分: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...
}