C++初学者继承问题

C++ Beginner Inheritance Issue

我是继承的新手,我很难理解它的一些概念。

我想做的是我有一个名为 Rectangle 的 class,它创建并绘制了一个矩形。我有另一个名为 Button 的 class,它是一个矩形,上面有文本并根据是否单击它来改变颜色。

我的 Rectangle class 用于其他领域和作品。我不确定如何让 Button class 按照我想要的方式从 Rectangle class 继承。

Rectangle.h

#ifndef _rectangle_h_
#define _rectangle_h_
#include <vector>
#include "glut.h"

class Rectangle
{
public:
    Rectangle(std::vector<int> p1, std::vector<int> p2, double color[3]);
    void Draw() const;

protected:
    std::vector<int> mP1;
    std::vector<int> mP2;
    double mColor[3];
};

#endif

Rectangle.cpp

#include "Rectangle.h"

Rectangle::Rectangle(std::vector<int> p1, std::vector<int> p2, double color[3])
{
    mP1 = p1;
    mP2 = p2;

    mColor[0] = color[0];
    mColor[1] = color[1];
    mColor[2] = color[2];
}


void Rectangle::Draw() const
{
    glColor3d(mColor[0], mColor[1], mColor[2]);

    glBegin(GL_QUADS);
    glVertex2d(mP1[0], mP1[1]);
    glVertex2d(mP2[0], mP1[1]);
    glVertex2d(mP2[0], mP2[1]);
    glVertex2d(mP1[0], mP2[1]);
    glEnd();
}

这是我正在尝试做的,但我不确定正确的语法是什么。 Button 可以使用 Rectangle 的点数 (mP1 and mP2) 和颜色 (mColor)。 Button不能继承RectangleDraw方法,因为Button也必须绘制文字,但确实需要调用RectangleDraw 方法来绘制实际的矩形。

我的问题是"How would I go about doing this?"

同样,下面是我认为正确的实现方法,但我知道这是不正确的,我想问的是正确的实现方法。

Button.h

#ifndef _button_h_
#define _button_h_

#include <vector>
#include <string>
#include "Rectangle.h"

class Button: public Rectangle
{
public:
    Button(std::vector<int> p1, std::vector<int> p2, std::string text);
    void Press();
    void Release();
    void Draw() const;

private:    
    bool mPressed;
    std::string mText;
};

#endif

Button.cpp

#include "Button.h"
#include <iostream>

Button::Button(std::vector<int> p1, std::vector<int> p2, std::string text)
{
    double color[3] = {.19,.75,1};
    Rectangle(p1,p2,color);
    mText = text;
}

void Button::Press()
{
    mPressed = true;

    mColor[0] = .19;
    mColor[1] = .34;
    mColor[2] = 1;
}

void Button::Release()
{
    mPressed = false;

    mColor[0] = .19;
    mColor[1] = .75;
    mColor[2] = 1;
}

void Button::Draw() const
{
    Rectangle::Draw();

    // I will worry about drawing the actual text later
    // for now I just want to make sure that I can print the text
    std::cout << mText << std::endl;  
}

Buttoncan't inherit Rectangle's Draw method because the Button must also draw the text, but it does need to call Rectangle's Draw method in order to draw the actual rectangle.

如果你想调用父类的draw方法做Rectangle::Draw()

你需要在Rectangle中写一个默认的构造函数来创建一个Button的对象,因为当你试图创建一个Button的对象时,它会尝试调用基础class构造函数。否则,您需要通过在初始化列表中调用基础 class 构造函数来更改派生 class 构造函数的构造函数定义。

现在您正在覆盖按钮中的函数 draw()。如果你更喜欢使用多态性,使用基class指针调用函数,你应该定义Rectangle::draw()应该定义为虚函数。

作为初学者,您应该遵守这些规则虔诚地:

  1. 每个可继承的 class 必须 有一个 virtual 析构函数。
  2. 每个可覆盖的方法必须virtual

调用父构造函数的语法如下:

Button::Button (std::vector<int> p1, std::vector<int> p2, std::string text) :
    Rectangle (p1, p2, color)
{
   // rest of Button constructor
}

您需要将 color 定义为 Button 的静态成员。

建议为 Color 和 Point 定义 classes 而不要使用 naked arrays/vectors。 std::vector 对于 2d 点是矫枉过正。使用 std::array 或仅 class Point {int x, y; ...};

继承是否适合您的情况值得商榷。也许如果您的 Button 的矩形仅用于绘制它,那么继承是不合适的。这样的按钮只是 使用 一个矩形来绘制自己。 OTOH 如果您的对象的边界是矩形并且这些边界用于对象交互,例如对于计算包含其他更小对象的对象,那么继承是最合适的。