0

我正在尝试编写一个类来处理操纵杆输入(不相关),并且对继承和 C++ 的新手感到生疏我在尝试创建操纵杆类的子类时遇到了一些困惑。这是我的代码

//superclass's .h
#ifndef JOYSTICKINPUT_H
#define JOYSTICKINPUT_H

#include "WPILib.h"

class JoystickInput {
    public:
        JoystickInput(Joystick*);
        Joystick * joystick;
        Victor * myVictor [3];
        bool buttons [10];
        bool buttonClicked(int id);
        void testForActions();
};
#endif

这是它的定义

//superclass's .cpp
#include "JoystickInput.h"

JoystickInput::JoystickInput(Joystick * joy) {
    joystick = joy;
    for (int x = 0; x < 10; x++) {
        buttons[x] = false;
    }
}

bool JoystickInput::buttonClicked(int id) {
    if (buttons[id] == false and joystick->GetRawButton(id) == true) {
        buttons[id] = true;
        return true;
    } else if (buttons[id] == true and joystick->GetRawButton(id) == false) {
        buttons[id] = false;
        return false;
    } else {
        return false;
    }
}

void JoystickInput::testForActions() {
}

现在我试图用 JoystickOne 类来扩展它,因为它的行为略有不同。为此,我创建了 JoystickOne.h 和 JoystickOne.cpp

//Joystickone.h
#ifndef JOYSTICKONE_H
#define JOYSTICKONE_H
#include "WPILib.h"
#include "JoystickInput.h"

class JoystickOne : public JoystickInput {
    public:
        JoystickOne(Joystick*);
        Joystick * joystick;
        Victor * myVictor;
        bool buttons [10];
        bool buttonClicked(int id);
        void testForActions();
};
#endif

和.cpp

    #include "JoystickOne.h"
#include "WPILib.h"

JoystickOne::JoystickOne(Joystick * joy) : JoystickInput(joy) {
    //joystick = joy;
    //myVictor = new Victor(1);
    /*for (int x = 0; x < 10; x++) {
        buttons[x] = false;
    }*/
}

bool JoystickOne::buttonClicked(int id) {
    if (buttons[id] == false and joystick->GetRawButton(id) == true) {
        buttons[id] = true;
        return true;
    } else if (buttons[id] == true and joystick->GetRawButton(id) == false) {
        buttons[id] = false;
        return false;
    } else {
        return false;
    }
}

void JoystickOne::testForActions() {
    if (buttonClicked(1)) {
    }
    if (buttonClicked(2)) {
    }
    if (buttonClicked(3)) {
        //myVictor->Set(.3);
    }
    if (buttonClicked(4)) {
    }
}

我的问题是我不太确定 JoystickOne 类中有什么无关紧要的东西。我来自 Java,所以我习惯于扩展一个超类并自动使用它的所有方法和成员。由于 C++ 分离为 .h 和 .cpp 文件,我感到很困惑;从我通过弄乱学到的知识中,我必须声明我希望使用的所有变量和方法,即使它们是超类的成员。我不认为我必须定义方法 buttonClicked() 两次,虽然我没有机器人,所以我现在无法实际测试它。

基本上,我在问我可以从 JoystickOne 类的定义中删除什么,以及如何去做。如果你们中的任何人对 C++ 中的一些良好 OOP 实践有任何建议,请随时分享,或者甚至清除我拥有的一些 Java 主义。

谢谢!

4

3 回答 3

4

您应该将可被覆盖的方法标记为virtual基类中的方法。要在派生类中覆盖它,只需在派生类中重新定义它。

例子:

class Base{
public:
  virtual void overrideThis() { std::cout << "Base" << std::end; }
  void test() { std::cout << "Base::test()" << std::endl; }
};

class Derived : public Base{
public:
  void overrideThis() { std::cout << "Derived" << std::endl; }
};

现在,如果您实例化:

Derived d;
d.overrideThis(); // Will print 'Derived'
d.test(); // Will print 'Base::test()'

至于成员变量。在您的基类中定义的私有成员将在您的派生类中不可用。另一方面,受保护的和公共的成员变量将是可访问的。

于 2013-05-01T20:49:15.163 回答
3

您需要使用virtual关键字来使您的函数可继承。此外,您可以声明函数,例如

buttonClicked(int id) = 0;

这将相当于一个抽象方法。

您不需要重新定义变量,如果是公共的或受保护的,它们应该自动继承。另请注意,您应该始终将析构函数声明为虚拟的,否则继承的类将无法删除自己的东西。

于 2013-05-01T20:49:43.510 回答
0

不,您不必在继承/子类中重新声明属性,因此请删除它们。通常将它们设为私有(仅父类可用)或受保护(父类和子类可用)不公开。使用您的方法,仅当它们在子类中的行为不同时才“重新声明”(覆盖),并确保在父类中将它们声明为虚拟。实验很好.. 删除一些东西,添加大量打印语句,然后看看它的行为:) 除了 .h/.cpp 之外,它与 Java* 并没有太大的不同。

*在基础级别

于 2013-05-01T20:51:33.843 回答