一个标题中的基类和派生类

时间:2013-11-13 12:55:20

标签: c++ oop inheritance

我想把两个clasess放在一个头文件中。一个是基类,第二个是从这个基类派生的,我的意思是这样的:

class Drawable{
public:

  Drawable();

  void setPosition(math::Vector3 position);

  void draw();

};

class Box: public Drawable{} ;

但我得到错误“未定义引用`Drawable :: Drawable()'”。在源文件中我有:

class Drawable {
public:
    math::Vector3 position;
    math::Vector3 rotation;

    Drawable() {
        position = math::Vector3(1.0, 1.0, 1.0);
        rotation = math::Vector3(0.0, 0.0, 0.0);
    }

    void setPosition(math::Vector3 position) {
        this->position = position;
    }

    void draw() {
    }
};

class Box: public Drawable {
public:
    void draw() {

        glBegin(GL_TRIANGLES);
        drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
        drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
        drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));

        drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
        drawPoint(this->position + math::Vector3(1.0f, 1.0f, -1.0f));
        drawPoint(this->position + math::Vector3(1.0f, -1.0f, 1.0f));
        glEnd();
    }
};

所以在我看来不可能实现这一点,因为头中的派生类还不知道基类的构造函数。我是对的吗?

4 个答案:

答案 0 :(得分:3)

你需要做这样的事情:

<强> example.h文件

class Drawable 
{ 
    public:

    Drawable();

    void setPosition(math::Vector3 position);

    virtual void draw();

    math::Vector3 position;
    math::Vector3 rotation;
};

class Box: public Drawable
{
    public:
    virtual void draw();
};

<强> example.cpp

#include "example.h"

Drawable::Drawable() {
    position = math::Vector3(1.0, 1.0, 1.0);
    rotation = math::Vector3(0.0, 0.0, 0.0);
}

void Drawable::setPosition(math::Vector3 position) {
    this->position = position;
}

void Drawable::draw() {
}

void Box::draw() {

    glBegin(GL_TRIANGLES);
    drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
    drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
    drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));

    drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
    drawPoint(this->position + math::Vector3(1.0f, 1.0f, -1.0f));
    drawPoint(this->position + math::Vector3(1.0f, -1.0f, 1.0f));
    glEnd();
}

标题定义:

  • 构造函数/析构函数签名
  • 会员变量
  • 会员功能签名

来源定义

  • 构造函数/析构函数实现
  • 会员功能实施

注意:使用范围解析运算符::来引用类成员。

答案 1 :(得分:2)

  1. 所有数据成员(如math::Vector3 position;)必须仅在头文件中定义,而不是在cpp中定义。
  2. cpp文件中方法的定义是:return_type class_name::function_name (parameters) { ... }
  3. 在您的情况下,
  4. draw应为virtual。甚至可能是纯虚拟的(如基类中的void draw() = 0;,并在派生中声明和实现)。

  5. 示例:

    ///////////////////////////////////////////
    // header
    class A
    {
    public:
        A();
        void f();
    private:
        int x;
    };
    
    /////////////////////////////////////////// 
    // cpp
    A::A() 
    { 
        /* constructor impl */ 
    }
    
    void A::f() 
    { 
        /* impl */ 
    }
    

答案 2 :(得分:1)

您将在源文件中实现您的方法,如下所示:

void Drawable :: setPositon(...){ //do stuff };

您正在声明一个与标题名称相同的新类!

答案 3 :(得分:0)

另外,看到你的position成员有一个setter函数,你应该把它变成私有的,并声明&amp;定义一个getter:

class Drawable{
private:
    math::Vector3 position;
    math::Vector3 rotation;
public:
    Drawable();
    void setPosition(math::Vector3 position);
    math::Vector3 getPosition();
    void setRotation(math::Vector3 rotation);
    math::Vector3 getRotation();
    void draw();
};

使用您当前的实现,调用setter会有点多余,因为您可以直接访问该成员而不是使用setter函数:

Drawable d;
d.position = math::Vector3(0,0,0);      //both do the
d.setPosition(math::Vector3(0,0,0));    //same thing