Предупреждение: перегружена виртуальная функция & quot; Base :: process & quot; только частично переопределяется в классе «производный»

Я получаю предупреждение ниже.
часть моего кода:

class Base {
public:
virtual void process(int x) {;};
virtual void process(int a,float b) {;};
protected:
int pd;
float pb;
};

class derived: public Base{
public:
void process(int a,float b);
}

void derived::process(int a,float b){
pd=a;
pb=b;
....
}

Я получаю предупреждение ниже:

 Warning: overloaded virtual function "Base::process" is only partially overridden in class "derived"

В любом случае, я сделал процесс виртуальной функцией, поэтому я ожидаю, что это предупреждение не должно появиться …
В чем причина этого ??

7

Решение

Причина предупреждения

Warning: overloaded virtual function "Base::process" is only partially overridden in class "derived"

является то, что вы не перезаписали все подписи, вы сделали это для

virtual void process(int a,float b) {;}

но не для

virtual void process(int x) {;}

Кроме того, когда вы не переопределяете и не используете using Base::process принести функции для охвата статических вызовов derived::process(int) даже не скомпилируется. Это потому что Derived не имеет process(int) в этом случае. Так

Derived *pd = new Derived();
pd->process(0);

а также

Derived d;
d.process(0);

не скомпилируется.

Добавление using Объявление исправит это, разрешив статический вызов скрытых функций через указатель на Derived * и выберите оператор d.process (int) для компиляции и для виртуальной диспетчеризации (вызов производного через базовый указатель или ссылку) для компиляции без предупреждений.

class Base {
public:
virtual void process(int x) {qDebug() << "Base::p1 ";};
virtual void process(int a,float b) {qDebug() << "Base::p2 ";}
protected:
int pd;
float pb;
};

class derived: public Base{
public:
using Base::process;

/* now you can override 0 functions, 1 of them, or both
*  base version will be called for all process(s)
*  you haven't overloaded
*/
void process(int x) {qDebug() << "Der::p1 ";}
void process(int a,float b) {qDebug() << "Der::p2 ";}
};

сейчас:

int main(int argc, char *argv[])
{
derived d;
Base& bref = d;
bref.process(1);    // Der::p1
bref.process(1,2);  // Der::p2
return 0;
}
6

Другие решения

При переопределении виртуального метода в классе любые перегрузки этого метода, которые не переопределяются, скрытый для этого класса и не может быть использован. Так что в вашем примере, пытаясь позвонить process(int) на derived объект потерпит неудачу, потому что переопределено process(int, float) спрятал это.

3

Вы перекрыли только одну из двух перегрузок process, Вы пропускаете перегрузку, принимая только int,

class Base {
public:
virtual void process(int x) {;}; // You do *not* override this in derived
virtual void process(int a,float b) {;}; // You do override this
// ...
};

В зависимости от того, что вы хотите, вы можете:

  1. Просто переопределить int перегрузка тоже в derived; или же

  2. сделать int перегрузите не виртуальный и позвольте ему вызывать виртуальный int, float перегрузки.

Два примечания: (а) Хотя большинство компиляторов принимают это, ; после того, как тело функции синтаксически неправильно. (б) Защищенные членские переменные обычно не одобряются почти так же, как публичные; Вы должны использовать защищенные методы получения / установки и делать переменные закрытыми.

1

C ++ разрешение перегрузки.

Короче говоря, частичное переопределение перегруженной функции может быть странным при попытке определить имя.

Кроме того, с точки зрения дизайна. образец вообще странный. У меня есть функция, которая, как я решил, является такой же, чтобы оправдать одно и то же имя: в целом, это молчаливое соглашение о том, что она делает то же самое. Когда вы изменяете поведение функции в дочернем классе, тогда странно, если вы изменяете только ее часть в производном. По сути, его легко читать (используя ~ = примерно равный)

// НЕПРАВИЛЬНЫЕ ЗАЯВЛЕНИЯ

1) Base :: process (int) ~ = Base :: process (int, float)

2) производная :: процесс (int) ~ = производная :: процесс (int, float)

// ЯВНЫЕ ЗАЯВЛЕНИЯ

3) Base :: process (int) == производная :: process (int)

4) Base :: process (int, float)! = Производная :: процесс (int, float)

по сути, поскольку 3 и 4 находятся в конфликте, то 2 не может быть правдой.

0

Когда вы объявляете метод с тем же именем, что и в Baseэти методы скрыты.

Это тот случай, когда вы переопределяете один метод.

Так

derived d;
d.process(42); // won't compile

Чтобы решить это: добавьте using Base::process:

class derived: public Base {
public:
using Base::process;
void process(int a, float b);
};

Как и предыдущий метод, не отключайте предупреждение
Другой способ решить это переопределить каждый метод process:

class derived: public Base {
public:
void process(x) { Base::process(x); }
void process(int a, float b);
};
0
По вопросам рекламы [email protected]