Подтвердить что ты не робот

Метод С++ доступен только при перемещении объекта в базовый класс?

В моем коде должно быть что-то конкретное, которое я не могу опубликовать. Но, возможно, кто-то может предложить возможные причины.

В основном я:

class CParent
{
 public:
  void doIt(int x);
};
class CChild : public CParent
{
 public:
  void doIt(int x,int y,int z);
};

CChild *pChild = ...
pChild->doIt(123); //FAILS compiler, no method found
CParent *pParent = pChild;
pParent->doIt(123); //works fine

Как на земле?

EDIT: люди говорят о теневом/скрытии. Но две версии doIt имеют различное количество параметров. Неужели это не может смутить компилятор, перегружает в дочернем классе, который нельзя путать с версией родительского класса? Может ли это?

Ошибка компилятора: ошибка C2660: 'CChild:: doIt': функция не принимает 1 аргумент

4b9b3361

Ответ 1

Вы затеняете метод. Например:

struct base
{
    void method(int);
    void method(float);
};

struct derived : base
{
    void method(int);
    // base::method(int) is not visible.
    // base::method(float) is not visible.
};

Вы можете исправить это с помощью директивы using:

class derived : public base
{
    using base::method; // bring all of them in.

    void method(int);
    // base::method(int) is not visible.
    // base::method(float) is visible.
};

Поскольку вы, похоже, настаиваете на количестве параметров, я обращусь к этому. Это ничего не меняет. Обратите внимание:

struct base
{
    void method(int){}
};

struct derived : base
{
    void method(int,int){}
    // method(int) is not visible.
};

struct derived_fixed : base
{
    using base::method;
    void method(int,int){}
};

int main(void)
{
    {
        derived d;

        d.method(1, 2); // will compile
        d.method(3); // will NOT compile
    }
    {
        derived_fixed d;

        d.method(1, 2); // will compile
        d.method(3); // will compile
    }
}

Он по-прежнему будет затенен независимо от параметров или типов возврата; это просто имя, которое тени. using base::<x>; приведет к появлению всех методов base "<x>".

Ответ 2

Вы сталкиваетесь с классической проблемой. Вам нужно using CParent::doIt; в вашем классе CChild. Я буду разбирать повторяющиеся вопросы.

Edit:

Здесь мой ответ по существу на тот же вопрос: Переопределение перегруженной базы в С++

Ответ 3

Я никогда не делал этого, не имея этого метода в базовом классе раньше. Я думаю, что добавление "использования CLASS:: METHOD" в производном классе даст вам доступ к другой версии перегруженного метода.

class CParent
{
 public:
  void doIt(int x);
};
class CChild : public CParent
{
 public:
  void doIt(int x,int y,int z);

  using CParent::doIt;
};

Ответ 4

Проблема CChild фактически не наследуется от CParent.

И поэтому у него нет метода doIt, который принимает только один аргумент.

Ответ 5

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

Поэтому ваш указатель pChild, вызывающий doIt (int x), потерпит неудачу, поскольку вы используете указатель производного класса для вызова функции базового класса. Указатель pParent, вызывающий doIt (int x), будет работать, так как вы используете указатель базового класса для вызова функции базового класса. Даже если у вас есть дочерний объект, на который указывает родительский указатель (вверх), тип класса здесь определяется объявлением указателя, который является CParent.

Чтобы иметь возможность вызвать эту функцию базового класса с помощью указателя производного класса, вы можете:

  • Определите имя базового класса в вызове функции, как показано ниже:

    pChild->CParent::doIt(123);

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

Ответ 6

Я понимаю, что это поведение позволяет вам переопределить поведение метода базового класса в производном классе.

Предположим, что у вас есть функция foo (int) в базовом классе и вы хотите изменить поведение этой функции в производном классе. Теперь, если метод базового класса не скрыт методом вашего производного класса (который имеет тот же прототип, что и метод базового класса), он будет вводить двусмысленность в разрешении перегрузки.

Ответ 7

Метод в вашем дочернем классе имеет другое количество аргументов, чем то, что вы пытаетесь передать в него. Может ли быть связано с этим?