Как перегрузить и вызвать метод в производном классе, который ранее был определен в его базовом классе?

Это базовый класс:

template <class T>
class DataLogger
{
        // ...
    public:
        void AddData(T Data);
        // ...
}

А это производный класс:

#include "DataLogger.h"
#include <utility>

class Plotter : public DataLogger<std::pair<long double, long double>>
{
        // ...
    public:
        void AddData(long double x, long double y);
        // ...
}

// This method is supposed to wrap the original AddData() method
// which was defined in the base class
void Plotter::AddData(long double x, long double y)
{
    AddData(std::make_pair(x, y));  // LINE #29
}

Данная ошибка:

СТРОКА 29: IntelliSense: не существует подходящей функции преобразования из "std::pair" в "long double"

LINE 29: IntelliSense: слишком мало аргументов в вызове функции

Судя по всему, проблема в том, что я не могу получить доступ к методу в базовом классе из производного класса, хотя он определен как общедоступный.

Как заставить этот код работать?

(Моя IDE — Visual Studio 2010.)


person hkBattousai    schedule 06.01.2011    source источник


Ответы (4)


Ваш AddData из базы скрыт AddData из производного класса. Либо явно определите вызов DataLogger<std::pair<long double, long double>>::AddData(...), либо поместите его в область действия с помощью using DataLogger<std::pair<long double, long double>>::AddData;

person Gene Bushuyev    schedule 06.01.2011
comment
DataLogger‹std::pair‹long double, long double››::AddData(...) это сработало. Но я не понимал механизма этого. AddData() в базовом классе не является статическим. Как мы можем назвать это в этом формате? - person hkBattousai; 06.01.2011
comment
Вы сообщаете компилятору, откуда этот метод. Более короткая версия гласит: ::AddData(..) -- использовать предыдущий родительский класс, в котором был объявлен AddData. - person Raphael Bossek; 06.01.2011
comment
@Rapheal B.: Когда я использую короткую версию ::AddData(), компилятор выдает эту ошибку: Ошибка C2039: «AddData»: не является членом «глобального пространства имен». - person hkBattousai; 06.01.2011

Ваш AddData в производном классе скрывает функцию AddData в базовом классе, поэтому все, что вам нужно сделать, это отобразить последнюю с помощью директивы using:

class Plotter : public DataLogger<std::pair<long double, long double>>
{

public:
   //unhiding : bringing base class function into scope!
   using DataLogger<std::pair<long double, long double>>::AddData;

};

Прочтите Совет 33. Не скрывайте унаследованные имена от Эффективный C++" Скотта Мейерса.

person Nawaz    schedule 06.01.2011

Чтобы вызвать метод класса super, напишите ::AddData(x, y);. Новый метод Plotter::AddData делает DataLogger::AddData невидимым.

person Raphael Bossek    schedule 06.01.2011
comment
На уроке ужина я проголодался ;) - person Moo-Juice; 06.01.2011

Проблема не в том, «что я не могу получить доступ к методу в базовом классе из производного класса, даже если он определен как общедоступный».

Проблема в том, что Plotter::AddData пытается вызвать себя (с парой) вместо AddData в базовом классе.

Вы можете сделать вызов явным, написав

void Plotter::AddData(long double x, long double y)
{
    DataLogger<std::pair<long double, long double>>::AddData(std::make_pair(x, y));
}
person Andrew Stein    schedule 06.01.2011