2012-05-04 3 views
1

Начиная с этого кода:Используйте виртуальный метод базового класса

class Base{ 
public: 
    virtual void foo(){....} 
}; 
class Derived{ 
public: 
    void foo(){....} 
}; 

Если d является Derived объект, я могу каким-то образом вызвать метод Foo, определенный в классе Base для этого объекта?

Edit: я имею в виду с внешней стороны, так что связывается с Base :: Foo()

+1

Вызов 'Base :: foo()'. –

+0

Да, я забыл указать. Снаружи. – Aslan986

+1

@ Aslan986: Вы действительно хотите это сделать? Вы действительно *, * действительно хотите сделать это? Во многих случаях довольно сложно заставить вызов выполнить конкретное * переопределение * ... вы можете привести к нежелательным результатам, сломанным инвариантам ... –

ответ

6

Укажите его в явном виде в вызове.

#include <iostream> 

class Base{ 
public: 
    virtual void foo(){ 
     std::cout << "Base" << std::endl; 
    } 
}; 
class Derived : public Base{ 
public: 
    void foo(){ 
     std::cout << "Derived" << std::endl; 

    } 
}; 

int main() 
{ 
    Derived d; 
    d.Base::foo(); 
    return 0; 
} 
+0

Это отвечает на вопрос и является правильным, но мне все еще кажется, что если вам нужно это сделать, что-то очень не так. –

+0

@JohnDibling Я только что прошел через другие ответы и должен согласиться. Есть что-то не так, но я был в ситуациях с устаревшим кодом, который требовал чего-то подобного, поэтому я оставил слово совета. Наличие способности вызывать функцию таким образом никогда не должно быть частью какого-либо дизайна. – pmr

3

Для вызова от внешнего кода, вы можете явно квалифицировать имя в вызове:

#include <iostream> 
#include <vector> 

struct base { 
    virtual void do_something() { std::cout << "Base::do_something();\n"; } 
}; 

struct derived : public base { 
    virtual void do_something() { std::cout << "derived::do_something();\n"; } 
}; 

int main() { 

    derived d; 

    d.base::do_something(); 
    return 0; 
} 

Если вы используете указатель на объект, вы бы изменить, что d->base::do_something(); ,

6

Просто квалифицируют вызов (при условии, что Derived фактически наследует от Base, что в вашем коде нет):

Derived d; 
d.Base::foo(); 

Теперь, когда это выполнимо, это также весьма сомнительна. Если этот метод является виртуальным, он должен быть переопределен, и пользователи не должны вызывать определенное переопределение, но final-overrider, иначе они рискуют полностью разбить инварианты класса.

Учтите, что реализация Derived::foo выполняла дополнительную работу, необходимую для хранения некоторого инварианта, если пользователи звонят Base::foo, что дополнительная работа не будет выполнена, а инвариант будет сломан, оставив объект в недопустимом состоянии.

+0

+1 это по-прежнему правильно в соответствии с параметрами вопроса, но лучше, потому что он обращается к тому, что, вероятно, беспорядок. –

Смежные вопросы