2015-04-12 3 views
0

Я новичок в наследовании, и у меня возникают проблемы с пониманием некоторых его концепций.C++ Beginner Inheritance Issue

Что я пытаюсь сделать, так это класс Rectangle, который создает и рисует прямоугольник. У меня есть другой класс под названием Button, который представляет собой прямоугольник с текстом на нем и изменяет цвет в зависимости от того, нажата ли кнопка или нет.

Мой класс Rectangle используется в других областях и работает. Я не уверен, как получить класс Button для наследования класса Rectangle так, как я его хочу.

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 не может наследовать Rectangle метод Draw, потому что Button также должен нарисовать текст, но для того, чтобы нарисовать реальный прямоугольник, необходимо вызвать метод .

Мой вопрос: «Как мне это сделать?»

Опять же, как я думаю, правильный метод реализации этого будет, но я знаю, что это неверно, и я спрашиваю, каким будет правильный способ сделать это.

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; 
} 
+0

Возможно, вы должны перефразировать. Здесь нет актуального вопроса. – dingalapadum

+0

Спасибо, я исправил это. – tysonsmiths

+0

сделать 'Rectangle :: Draw' виртуальным (и переопределить его)? – Kevin

ответ

2

Как новичок, вы должны соблюдать эти правила религиозно:

  1. Каждый наследуемый класс обязательно имеют virtual деструктор.
  2. Любой способ, который можно преодолеть должен be virtual.

Синтаксис для вызова родительского конструктора заключается в следующем:

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

Вам нужно определить color как статический член Button.

Рекомендуется определять классы для цвета и точки, а не использовать голые массивы/векторы. std::vector для 2-го пункта - это излишество. Использовать std::array или только class Point {int x, y; ...};

Возможно ли наследование в вашем случае или нет, является спорным. Возможно, если прямоугольник вашей Button используется только для рисования, то наследование не подходит. Такая кнопка просто использует прямоугольник для рисования. OTOH, если границы ваших объектов являются прямоугольниками, и эти границы используются для взаимодействия объектов, например. для вычисления объекта, который содержит другие более мелкие объекты, то наследование является наиболее подходящим.

-1

Buttoncan't наследует метод Рисования прямоугольника, потому что кнопка должна также нарисовать текст, но это нужно вызвать Жеребьевка прямоугольника метод для рисования фактического прямоугольника.

Если вы хотите вызвать суперкласс метода рисования сделать прямоугольник :: Draw()

0

Вам нужно написать конструктор по умолчанию в прямоугольнике, чтобы создать объект Button, потому что при попытке создать объект Button, он попытается вызвать конструктор базового класса. В противном случае вам нужно изменить конструкторное определение конструктора производного класса, вызвав конструктор базового класса в списке инициализации.

Теперь вы отменяете функцию draw() в кнопке. Если вы предпочитаете использовать полиморфизм, чтобы вызвать функцию с помощью указателя базового класса, вы должны определить, что Rectangle::draw() должно быть определено как виртуальная функция.

+0

Надеюсь, я понимаю, что вы говорите. «написать конструктор по умолчанию в Rectangle для создания объекта Button». Проблема с этим заключается в том, что я использую «Rectangle» в других местах, поэтому я бы не захотел создать «Button», когда я использую «Прямоугольник» под разными обстоятельства. Наряду с этим, будет вызываться 'Rectangle :: draw()' virtual cause 'Button' для вызова каждый раз, когда я хочу нарисовать' Rectangle'? Потому что снова я использую «Прямоугольник» в других обстоятельствах. – tysonsmiths

+0

С предлагаемыми изменениями вы можете создавать Rectangle, когда захотите. Конструктор по умолчанию для Rectangle не имеет никаких аргументов. Если вы создадите Rectangle путем передачи аргументов, он вызовет конструктор Rectangle, который имеет соответствующие параметры. Для вашего второго вопроса, если вы назначаете указатель на кнопку на указателе Rectangle, тогда в картину будет входить только полиморфизм. Итак, как вы собираетесь создавать свой объект, важно, я имею в виду, что все параметры, передаваемые конструктору, и какой класс инициализируется, важно для определения влияния полиморфизма. – Steephen