-1

I'm currently converting a project from Java into C++. I'm using base classes as interface classes and I'm using derived classes as a subclass of the "interface" class. Right now, I'm having an issue regarding base and derived classes. Here's some of the code in the CPP file:

enum class State {
    START, INTEGER, DECIMAL, END
};

class Edge {
    private:
        State currentState;
        InputVerifier inputVerifier;
        Action action;
        State nextState;
    public:
        Edge(State _currentState, InputVerifier _inputVerifier, Action _action, State _nextState) {
            currentState = _currentState;
            inputVerifier = _inputVerifier;
            action = _action;
            nextState = _nextState;
        }
};

Edge machine[1] = {
    Edge(State::START, DigitInputVerifier(), ValueIsDigitAction(), State::INTEGER)
};

And some of the code in the header file:

class InputVerifier {
    public:
        virtual bool meetsCriteria(char c) = 0;
};

class Action {
    public:
        virtual InterimResult execute(InterimResult x, char c) = 0;
};

class ValueIsDigitAction: public virtual Action {
    public:
        InterimResult execute(InterimResult x, char c) override {
            x.setV(c - '0');
            return x;
        }
};

class DigitInputVerifier: public virtual InputVerifier {
    public:
        bool meetsCriteria(char c) override {
            if (c >= '0' && c <= '9') {
                return true;
            }
        return false;
        }
};

InterimResult is another class but that's not an issue. I've been trying to compile this but one of the errors I keep on getting is error: cannot declare parameter '_inputVerifier' to be of abstract type 'InputVerifier'. I've been trying to search this issue up but I'm not having much luck. I'm new to using classes in C++ so I'm trying to learn but I don't understand how to fix this error. If you could, could you explain what a pure virtual function is too? Any help would be greatly appreciated.

NickS
  • 1
  • 1
  • The error explicitly shows you the error: the class `InputVerifier` is abstract because of the `virtual bool meetsCriteria(char c) = 0;` abstract method. You cannot create instances of this class. – Dmitry Kuzminov Jun 03 '21 at 03:31
  • `InputVerifier` is an abstract class because it has pure virtual function. You cannot create an object of it. You could have pointer `InputVerifier*` as member and can pass any child class object that implements the virtual functions though. In this case `DigitInputVerifier` – Wander3r Jun 03 '21 at 03:32
  • Just to be clear, what I'm trying to achieve is a sort of superclass and subclass relation where I have one superclass and I can have many subclasses. The superclass variable will be assigned to whatever subclass I want to assign to it. Also, when I try to make the variable a pointer, I get "undefined reference to WinMain@16", which apparently means the application is trying to create a windows application rather than a console application. – NickS Jun 03 '21 at 03:35

1 Answers1

0

C++ is not Java. Obviously. One of the consequences is that the parameters could be passed either by value or by reference. Regarding InputVerifier that means that:

  • The InputVerifier inputVerifier is an attempt to create an instance of the class InputVerifier (and this class is abstract, so no instances are allowed).
  • The parameter InputVerifier _inputVerifier is passed by value, so again: this is an attempt to create a class that cannot be created.
  • There is an attempt of a deep copy inputVerifier = _inputVerifier;
  • When you pass the DigitInputVerifier() argument, you actually create a temporary object (it will be destroyed right after the expression is evaluated), and that this value is being copied to be passed by value.

The same applies to Action.

What you might want is:

class Edge {
    private:
        State currentState;
        InputVerifier &inputVerifier;
        Action &action;
        State nextState;
    public:
        Edge(State _currentState, InputVerifier &_inputVerifier, Action &_action, State _nextState)
            : currentState(_currentState),
              inputVerifier(_inputVerifier),
              action(_action),
              nextState(_nextState) {
        }
};

DigitInputVerifier digitInputVerifier;
ValueIsDigitAction valueIsDigitAction;
Edge machine[1] = {
    Edge(State::START, digitInputVerifier, valueIsDigitAction, State::INTEGER)
};

One more thing: public virtual is a special type of inheritance, and I guess that you don't need it. Simple class DigitInputVerifier: public InputVerifier would be enough.

Dmitry Kuzminov
  • 6,180
  • 6
  • 18
  • 40
  • So I've implemented that but I got this error: "undefined reference to `WinMain@16'". Help? – NickS Jun 03 '21 at 03:58
  • You need to define the `main` function (or WinMain, depends on the platform). I would advise you to study the basics of C++ and the simple Windows app example from MSVC. – Dmitry Kuzminov Jun 03 '21 at 04:05