Интервью на вопрос о виртуальных функциях в C ++ - PullRequest
20 голосов
/ 16 июня 2010

Мне задали этот безумный вопрос.Я был не в себе.

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

Возможно ли это?

Ответы [ 8 ]

50 голосов
/ 16 июня 2010

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

Это полиморфизм.

Если вы спрашиваете, с указателем базового класса на производный класс, можете ли вы вызвать метод базового класса, который переопределяется производным классом? Да, это также возможно, явно указав имя базового класса:

basePtr->BaseClass::myMethod();

16 голосов
/ 16 июня 2010

Попробуйте:

class A            { virtual void foo(); }
class B : public A { virtual void foo(); }

A *b = new B();
b->A::foo ();
10 голосов
/ 16 июня 2010

Да - вы должны указать полное имя:

#include <iostream>

struct base { 
    virtual void print() { std::cout << "Base"; }
};

struct derived : base {
    virtual void print() { std::cout << "Derived"; }
};

int main() { 
    base *b = new derived;
    b->base::print();
    delete b;
    return 0;
}
10 голосов
/ 16 июня 2010

Ты имеешь в виду что-то вроде этого. (Где pBase имеет тип указатель-на-основание, а объект-указатель на самом деле имеет тип Derived, производный от Base.)

pBase->Base::method();

Да, это возможно.

5 голосов
/ 16 июня 2010

Если я правильно понял вопрос, у вас есть

class B 
{
public: 
    virtual void foo();
};

class D: public B
{
public:
    virtual void foo();
}

B* b = new D;

И вопрос в том, можете ли вы позвонить B::foo(). Ответ - да, используя

b->B::foo()
0 голосов
/ 13 марта 2012
class B { 
    public: virtual void foo(); 
};

class D: public B { 
    public: virtual void foo() 
    { 
        B::foo();
    }; 
}

B* b = new D;

Решения:

  1. b->foo();
  2. b->B::foo()

  3. ИЛИ не отменять / не определятьfoo () в производном классе D и вызовите b-> foo ()

  4. B objb = *b; objb.foo() ; // this is object slicing and not (*b).foo() as in one of the previous answers

0 голосов
/ 18 июня 2010
class B 
{
public: 
    virtual void foo();
};

class D: public B
{
public:
    virtual void foo();
}

B* b = new D;

Попробуйте позвонить

(*b).foo()

для вызова функции foo базового класса

0 голосов
/ 16 июня 2010

Нет.Не в чистом виде.Но да.Вы должны сделать некоторые манипуляции с указателями, получить указатель на vtable и сделать вызов.но это не совсем указатель на базовый класс, а некоторая умная манипуляция указателем.Другой подход заключается в использовании оператора разрешения области видимости в базовом классе.

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