无法从派生类转换为基类

时间:2014-05-27 13:51:36

标签: c++

我无法解决它。我有两个班:

Spatial.h:

namespace graphics {

class Scene;
class Node;
/**
 * Spatial is the basic object that builds the scene. Every class that happens to be in the scene is a spatial
 * 
 */
class Spatial {

public:

    /** A spatial must be renderable */
    virtual void render() = 0;

    /** Get the scene that the spatial belongs to*/
    Scene* getScene();

    /** Set the parent of this spatial to node or to null */
    virtual void setParent(Node* parent) ;


protected:
    /** The scene that the spatial belongs to */
    Scene* scene;

    /** The parent element of the spatial */
    Spatial* parent;


private:


};

}

Spatial.cpp:

namespace graphics {

    Scene* Spatial::getScene() {
        return this->scene;
    }

    void Spatial::setParent(Node* parent) {
        this->parent = parent; // ERROR: cannot convert 'graphics::Node*' to 'graphics::Spatial*' in assignment

        printf("set parent from spatial");
    }
}

Node.cpp:

namespace graphics {

    /**
     * Render the children elements of the node
     */
    void Node::render() {
        for (int i = 0 ; i < children.size(); i++) {
            Spatial* child = children.at(i);
            child->render();
        }
    }

    void Node::addChild(Spatial* spatial) {
        children.push_back(spatial);
        spatial->setParent(this);
    }

    void Node::setParent(Spatial* parent) {
        printf("setparent from node"); 
    }

}

Node.h

namespace graphics {

    using namespace std;

    /** 
     * Node contains different spatial elements which can be rendered from inside of it 
     * If node contains other nodes, then the rendering process is said to recursive:
     * - first element to be drawn in this case is the deepest drawable spatial
     */
    class Node : public Spatial {
    public:
        Node();
        Node(const Node& orig);

        /** Render all childrens of the node within a given scene */
        virtual void render();

        /** Add a child to this node*/
        void addChild(Spatial* spatial);

        /** temporrar y*/
        virtual void setParent(Spatial* parent);

        virtual ~Node();

    protected:

        /** All the children elements of the Node */
        vector<Spatial*> children;


    private:

    };
}

在编译时我收到错误:

  

无法将'graphics :: Node *'转换为'graphics :: Spatial *'   任务....

为什么呢?我正在为基类指针分配一个派生类指针。在其他地方它的工作原理。这有什么问题?

4 个答案:

答案 0 :(得分:1)

问题是你还没有在Spatial.cpp中包含Node.h,所以编译器并不知道它们是相关的。

您设法通过不完整的类型声明获得Node的基本识别,但这还不够。您需要在Spatial.cpp中包含Node.h才能完成图片。

答案 1 :(得分:0)

问题是,不是“为什么”,而是Node中的Node.h声明在哪里?”。当编译器解析Node.h时,应该告诉它它是Spatial的子类。我想你只是混淆了定义文件(*.cpp)和声明文件(*.h)。

另外 - 如果你想通过指针调用类的成员函数,你应该使用operator->,而不是operator .

答案 2 :(得分:0)

在我意识到之前(删除)的答案是错误的并且在对代码进行一些调整之后,我能够使用vs2010进行编译。但也许以下内容可能有所帮助:

this-&gt; parent = dynamic_cast(parent)

答案 3 :(得分:0)

您的代码(简称)

class B;

class A
{
    A* pointerToB;
public:
    void setPointer(B* b)
    {
        pointerToB = b;
    }
};

class B : public A
{
};

...不起作用,因为当时编译器(*)&#34;工作&#34;在pointerToB = b它真的不知道,B是什么 - 通过前向声明它只知道类B存在。

可行的(可能包括其他可能性)是:

class B;

template<typename T>
class A
{
    A* pointerToB;
public:
    void setPointer(T* b)
    {
        pointerToB = b;
    }
};

class B : public A<B>
{
};

现在,编译器在第一次需要时创建A<B>,这是B的声明。但然后它知道B派生自 A

甚至还有一个名称:Curiously Recurring Template Pattern或CRTP。

(*)使用VS2012。