2015-09-23 1 views
0

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

В файле:

struct A{ 
    virtual int auu() { return 41; } 
}; 
struct B{ 
    virtual int boo() { return 43; } 
}; 

В другом файле:

#include <path to A, B> 
struct C : public A, public B{ 
    int auu() { return 20; } 
    int boo() { return 22; } 
}; 

И еще один файл:

#include <declaration of A and B, but not C> 

void doSth(A* a) 
{ 
    B * b = dynamic_cast<B*>(a); 
    /* I can only call auu with a */ 
    a->auu(); 
    /* I can only call boo with b */ 
    b->boo; 

    /* Something like this would be ideal: */ 
    <??? type> * C_interface = dynamic_interface_cast<B*>(a) 
    C_interface->auu(); 
    C_interface->boo(); 
} 

Так там называют как AUu и Замен только через один указатель переменная и без знания реализации C (не отбрасывая ее)? Также я бы хотел избежать создания иерархии наследования, которая НЕ связана с классом C.

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

EDIT: В реале А и В являются абстрактными. A - объект Simulation, который имеет такие методы, как size() и length(). B - это интерфейс ввода-вывода, реализующий геттеры и сеттеры, но он не знает о размерах, поэтому мне приходится использовать оба интерфейса во многих вычислениях. C - специализированное моделирование, которое реализует бывшие 2.

EDIT: Я переписал вопрос, может быть, это на самом деле имеет смысл сейчас.

+5

Дизайн выглядит сломанным ... чего вы пытаетесь достичь? Бросок из B в A логически неверен. –

+4

Танк - это транспортное средство с пушкой. может ли случайный пушечный диск? может выстрел случайного транспортного средства? это то, что вы предлагаете. –

+0

Неверно указан неверно? Если я отбрасываю от A до C, а затем от C до B, я получаю тот же результат, что и отбрасывание A до B, я полагаю? – MatrixAndrew

ответ

1

Я расскажу о том, что я сделал в своем комментарии. Совершенно легально бросить между братьями и сестрами, если фактический объект получен из обоих.

#include<iostream> 
using namespace std; 

struct A{ 
    virtual int auu() { return 41; } 
}; 
struct B{ 
    virtual int boo() { return 43; } 
}; 

struct C : public A, public B{ 
    int auu() { return 20; } 
    int boo() { return 22; } 
}; 

void take_B(B* bp) 
{ 
    cout << bp->boo() << endl; // expected 
    cout << "(The base class would say " 
     << bp->B::boo() << ")" << endl; // base class implementation 

    A *ap = dynamic_cast<A*>(bp); 
    if(!ap) 
    { 
     cerr << "weird, this cast should be possible!" << endl; 
    } 
    else 
    { 
     cout << ap->auu() << endl; // should work 
     cout << "(The base class would say " 
      << ap->A::auu() << ")" << endl; // base class implementation 
    } 
} 

int main() 
{ 
    C c; 
    take_B(&c); 

    cout << endl << "... and again:" << endl; 
    // just to clarify: The actual pointer type is irrelevant. 
    B *bp = &c; 
    take_B(bp); 

    return 0; 
} 
+0

Я вижу, хорошая демонстрация. Хотя то, что я хотел сделать, может быть достигнуто, если A и B должны были наследовать обычный, предпочтительно пустой класс, правильно? (с другой стороны, это создаст довольно хрупкий код, в конце концов, я думаю) – MatrixAndrew

+1

Нет, конечно, нет! Подумайте об этом - если оба D1 и D2 унаследованы от пустого B, их «специальности» не будут связаны. Например, объект D1 не будет иметь элементов данных, определенных в D2, к которым могут обращаться методы D2. Если код для таких функций D2 выполняется на объекте D1, он будет получать доступ к памяти, которая, как оказалось, находится на этом смещении в D2, но не имеет соответствия в D1 (не говоря уже о более сложных проблемах с раскладкой). Если вы набираете вызов '((D2 *) d1p) -> d2method()', вы вызываете его на неправильный объект. A D1 * не * a D2. (Но оба они, конечно, Bs.) –

+0

Да, конечно, я понял. На самом деле это тема, которая может быть объяснена в секундах визуально, а не мышления в указателях :)) – MatrixAndrew

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

  • Нет связанных вопросов^_^