我刚刚开始使用该语言超过一年后再次进入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;类型的变量并将其传递给方法)但没有任何效果,所以我想我会问这里。
答案 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...
}