2013-04-16 3 views
2

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

#include <iostream> 
#include <string> 

using namespace std; 

struct A 
{ 
    virtual string do_a() const = 0; 
    virtual void set_foo(int x) = 0; 
    virtual int get_foo() const = 0; 
    virtual ~A() {} 
}; 

struct B 
{ 
    virtual string do_b() const = 0; 
    virtual void set_foo(int x) = 0; 
    virtual int get_foo() const = 0; 
    virtual ~B() {} 
}; 

struct C : public A, public B 
{ 
    C() : foo(0) {} 
    string do_a() const { return "A"; } 
    string do_b() const { return "B"; } 
    void set_foo(int x) { foo = x; } 
    int get_foo() const { return foo; } 
    int foo; 
}; 

int main() 
{ 
    C c; 
    A& a = c; 
    B& b = c; 
    c.set_foo(1); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
    a.set_foo(2); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
    b.set_foo(3); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
} 

Этот код компилируется в г ++ 4.1.2 (по общему признанию, старые), используя -std = C++ 98 -pedantic -Wall -Wextra -Werror. Выходной сигнал:

A1 
B1 
AB1 
A2 
B2 
AB2 
A3 
B3 
AB3 

Это то, чего я хочу, но я сомневаюсь, работает ли это вообще или только «случайно». По сути, это мой вопрос: могу ли я зависеть от этого поведения, или должен ли я всегда наследовать от виртуального базового класса для этого типа сценария?

+0

Это действительно так, как работает C++. Вы можете зависеть от этого, хотя лично я нахожу это опасным сбивающим с толку (например, что-то имеющее отношение к множественному наследованию, если на то пошло, но это только я. И иногда у нас нет выбора ...). – syam

+0

Это основное поведение правильного компилятора C++. Это было бы так же, как и с более старыми или более новыми компиляторами. :-) – iammilind

+0

@syam Ознакомьтесь с термином «окончательный переулок» и ознакомьтесь с разделом 10.3 в стандарте. Можете позаботиться о некоторой путанице. –

ответ

3

Не делайте это сложнее, чем есть. Функция с той же сигнатурой, что и виртуальная функция в базовом классе, переопределяет базовую версию. Неважно, сколько у вас баз или какая другая база имеет виртуальную функцию с одной и той же сигнатурой. Итак, да, это работает.

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