0

I use avr-gcc and in my project are three devices which are able to output characters (Bluetooth, LCD, serial port). So I wrote three classes which implement the method ClassName* write(const char c). Now my idea was to write an abstract class which has the virtual method ReturnType* write(const char c) and implements some other methods like ReturnType* write(const char* c) or ReturnType* writeInt(const int16_t i) etc.

So I came to this:

template <class ReturnType>
class OutDevice {
    public:
        virtual ~OutDevice();

        virtual ReturnType* write(const char c) = 0;

        ReturnType* write(const char * c) {
            while (*c) {
                write(*c++);
            }
            return this;
        }
};

But when I try to use this abstract class in one of my three normal classes, I got a weird error:

#include "OutDevice.h"

class Display : public OutDevice<Display> {
    private:
        void send(uint8_t control, uint8_t data) {
            //some stuff
        }

    public:
        Display* write(const char c) { //error:   initializing argument 1 of 'virtual Display* Display::write(char)' [-fpermissive]
            send(_BV(IOC2), c);
            return this;
        }

        Display* write(const uint8_t row, const uint8_t column, const char* text) {
            setCursorPos(row, column);
            write(text); //error: invalid conversion from 'const char*' to 'char' [-fpermissive]
            return this;
        }
};

On line 10 I got this error:

error: initializing argument 1 of 'virtual Display* Display::write(char)' [-fpermissive]

What is the best way to do what I want or what am I doing wrong?

Thank you!

Edit: Added an extra method and the error avr-gcc gives me.

1 Answers1

1

You declared the argument as const char:

Display* write(const char c) 

This is probably a mistake, since the base class method takes a const char* instead:

ReturnType* write(const char * c)

This mismatch leads to an error when you try to call the method with a const char* argument.


Even if it's not a mistake, the effect is the same. The declaration of a write() function hides the declarations of any overloads from the base class. So the overwritten function is the one the compiler tries to call, other base class methods are not considered.

To bring the other overloaded functions from the base class "into scope", add a using declaration to the derived class:

using OutDevice::write;

With this, the correct overload should be called.

sth
  • 222,467
  • 53
  • 283
  • 367
  • No. this is right. In the base class there is also the virtual method `ReturnType* write(const char c)`. In the Display class I overwrite this virtual method. And now I want be able to use the implemented method in the base class within the Display class. – user2280245 Jun 11 '14 at 00:07
  • @user2280245: I've added some more to my answer concerning the new information. – sth Jun 11 '14 at 00:36
  • Thank you. `using` was the keyword I needed. – user2280245 Jun 11 '14 at 11:02