Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Множественное наследование 
:(
    Опции темы
HappyLife
Дата 24.12.2007, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: 3
Всего: 8



Здраствуйте. В ходе разработки программы возник вопрос. В случае положительного на него ответа мне не придется сильно менять мой код.
Внимание вопрос.

Можно ли как-нибудь сделать вот такую конструкцию?
Код

class A
{
public:
    int GetZ(){/*...*/}
};

class B
{
public:
    virtual int GetZ() = 0;
};

class C : public A,public B
{
/*...*/
};

B * GetC()
{
    return new C;
}
int main()
{
    B * b = GetC();
    b->GetZ(); // Должен вызвать A::GetZ();
    return 0;
}

PM MAIL   Вверх
bsa
Дата 24.12.2007, 16:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



нет. так нельзя.
PM   Вверх
Ln78
Дата 24.12.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: 13
Всего: 15



HappyLife, если под понятие "как-нибудь" подходит такой вариант
Код

class A
{
public:
   int GetZ()
   {
      printf("A\n");
      return 11;
   }
};

class B
{
public:
   virtual int GetZ() = 0;
};


class C : public A,public B
{
public:
  virtual int GetZ()
  {
     printf("C\n");
     return 12;
  }
};

B * GetC()
{
   return new C;
}
int main()
{
   B * b = GetC();
   b->GetZ(); // Должен вызвать A::GetZ();
   ((A*)((C*)&b))->GetZ();
   return 0;
}

то можно smile 
PM MAIL   Вверх
Earnest
Дата 24.12.2007, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Наверное все-таки смысл в том, чтобы C::GetZ имплементировался через метод A:

Код

class C: public A, public B
{
   virtual int GetZ()
   {
      return A::GetZ();
   }
};

Собственно, нормальный способ - интtрфейс + имплементация. Только вот вызов все же придется делать явно - компилятор не догадается, что из двух методов с одинаковыми именами нужно взять реализованный. Вот если бы оба класса шли от одного корня, да с виртуальным наследованием, да метод GetZ был абстрактным методом, определенным в корневом классе, то тогда компилятор бы догадался (правда, предупреждение все же выдал бы).
Т.е. примерно так:
Код

class Interface1
{
   virtual int GetZ() = 0;
};

class Interface2: virtual public Interface1
{
  // еще виртуальные методы
};

class Impl1: virtual public Interface1
{
   virtual int GetZ() { ... } // реализация
};

class Impl2: public Interface2, public Impl1
{
   // вот здесь переопределять метод GetZ не надо - будет взят метод из Impl1
};



--------------------
...
PM   Вверх
Random13
Дата 26.12.2007, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 21.11.2007

Репутация: нет
Всего: нет



Не вижу проблемы. На самом деле в методе класса В написано не что иное, как
{return ptrVTable -> GetZ();} (один из доводов того, что я говорил, что С++ написан на Си).
Виртуальные методы на С++ псевдовиртуальные, просто они перенаправляют в таблицу виртуальных функций. А так - это обычный метод. И на Си можно такую таблицу самому создать и туда перенаправлять запрос.

В класс С входит и А и В с их методами и переменными, при кастинге на А попадаешь в его методы и данные, при кастинге на В в его. Обращаться же напрямую из С к этому методу без кастинга некорректно, как и к любым одноименным полям предков в этом случае множественного наследования.

Код

int main()
{
    B * b = GetC();
    b->GetZ(); // Должен вызвать A::GetZ();
    return 0;
}

Просмотрел малость. не не не, если поинтер на b, то вызовется метод класса  b.
В::GetZ();


Единственное как вижу можно выкрутится, если такое нужно - внутри метода класса В делать указатель на А и возвращать его метод, что-то типа
Код

class C;
class A;
class B{
C *pC;
B() { pc = this; }
или
SetpC(C* pc) {pC = pc;}
...
}

int B::GetZ(){ A * a = pC; return a->GetZ();}


Это сообщение отредактировал(а) chipset - 30.12.2007, 10:44
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0498 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.