1

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

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

4 回答 4

3

你需要做这样的事情:

例子.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();
};

例子.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();
}

标题定义:

  • 构造函数/析构函数签名
  • 成员变量
  • 成员函数签名

源定义

  • 构造函数/析构函数实现
  • 成员函数实现

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

于 2013-11-13T13:00:01.727 回答
2
  1. 所有数据成员(如math::Vector3 position;)必须仅在头文件中定义,而不是在 cpp 中。
  2. cpp文件中一个方法的定义是:return_type class_name::function_name (parameters) { ... }
  3. draw应该是virtual你的情况。甚至可能是纯虚拟的(如void draw() = 0;在基类中并在派生类中声明和实现)。

例子:

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

/////////////////////////////////////////// 
// cpp
A::A() 
{ 
    /* constructor impl */ 
}

void A::f() 
{ 
    /* impl */ 
}
于 2013-11-13T13:00:57.663 回答
1

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

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

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

于 2013-11-13T12:59:21.240 回答
0

此外,由于您的成员有一个 setter 函数position,您可能应该将其设为私有,并声明和定义一个 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
于 2013-11-13T13:12:04.077 回答