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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться с конструктором, Конструктор при множественном наследован 
:(
    Опции темы
novice2011
Дата 23.7.2011, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Код

#include <string>
 
class Worker   // an abstract base class
{
private:
    std::string fullname;
    long id;
public:
    Worker() : fullname("no one"), id(0L) {}
    Worker(const std::string & s, long n)
            : fullname(s), id(n) {}
    virtual ~Worker() = 0; // pure virtual function   
};
 
class Waiter : virtual public Worker
{
private:
    int panache;
public:
    Waiter() : Worker(), panache(0) {}
    Waiter(const std::string & s, long n, int p = 0)
            : Worker(s, n), panache(p) {}
    Waiter(const Worker & wk, int p = 0)
            : Worker(wk), panache(p) {}    
};
 
class Singer : virtual public Worker
{
private:    
    int voice;
public:
    Singer() : Worker() {}
    Singer(const std::string & s, long n, int v = 0)
            : Worker(s, n), voice(v) {}
    Singer(const Worker & wk, int v = 0)
            : Worker(wk), voice(v) {}   
};
 
// multiple inheritance
class SingingWaiter : public Singer, public Waiter
{
public:
    SingingWaiter()  {}
    SingingWaiter(const std::string & s, long n, int p = 0,
                            int v = 0)
            : Worker(s,n), Waiter(s, n, p), Singer(s, n, v) {}
    SingingWaiter(const Worker & wk, int p = 0, int v = 0)
            : Worker(wk), Waiter(wk,p), Singer(wk,v) {}
    SingingWaiter(const Waiter & wt, int v = 0)
            : Worker(wt),Waiter(wt), Singer(wt,v) {}
    SingingWaiter(const Singer & wt, int p = 0)
            : Worker(wt),Waiter(wt,p), Singer(wt) {}
    
};


Не пойму один момент. В конструкторе:

SingingWaiter(const Waiter & wt, int v = 0) : Worker(wt),Waiter(wt), Singer(wt,v) {}

Worker(wt) - это Worker(const Waiter & wt), здесь используется Worker(const Worker & wk), которому по ссылке передается объект произв. класса, здесь понятно. 

Waiter(wt) - это Waiter(const Waiter & wt), я так понимаю, что здесь конструктор произв. класса вызывает конструктор базового класса по умолчанию, а в своем классе производит почленное копирование.

Singer(wt, v) - вот здесь мне не понятно, может быть кто-нибудь объяснит? Буду очень признателен.
Я так понимаю, что Singer(wt, v) - это Singer(const Waiter & wt, v), но в классе Singer нет такого конструктора.

Это фрагмент кода из книги Стивена Прата.
    

Это сообщение отредактировал(а) novice2011 - 23.7.2011, 16:54
PM MAIL   Вверх
boostcoder
Дата 23.7.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(novice2011 @  23.7.2011,  16:25 Найти цитируемый пост)
но в классе Singer нет такого конструктора.

как же?! вот он:
Код

Singer(const Worker & wk, int v = other)


Добавлено через 3 минуты и 6 секунд
вот только не понятно кто такой other..

Добавлено через 4 минуты и 23 секунды
очень жестокое наследование ты замутил smile 
PM WWW   Вверх
novice2011
Дата 23.7.2011, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Уважаемый boostcoder, да вместо other должен быть 0, здесь поторопился, в вышеприведенном коде исправил эту оплошность, но ведь

 Singer(const Waiter & wt, v) и Singer(const Worker & wk, int v = 0) это разные конструкторы?
Ведь в конструктор Singer передается объект  Waiter, а не Worker.

Это сообщение отредактировал(а) novice2011 - 23.7.2011, 17:02
PM MAIL   Вверх
boostcoder
Дата 23.7.2011, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(novice2011 @  23.7.2011,  16:45 Найти цитируемый пост)
Ведь в конструктор Singer передается объект  Waiter, а не Worker.

протупил. не заметил что это разные типы.

хм..

Добавлено через 9 минут и 22 секунды
ну так у Waiter`а предок - Worker.
PM WWW   Вверх
borisbn
Дата 23.7.2011, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(novice2011 @  23.7.2011,  16:45 Найти цитируемый пост)
Ведь в конструктор Singer передается объект  Waiter, а не Worker.

если мне не изменяет память, то ссылка (также как и указатель) на производный объект может быть преобразована к ссылке на базовый.
Т.е. в данном случае происходит следующее
Код

class Base {};
class Deriv : public Base {};

Deriv d;

const Base & bs = d;

и это - нормально !

Это сообщение отредактировал(а) borisbn - 23.7.2011, 17:04


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
novice2011
Дата 23.7.2011, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Уважаемый borisbn, но ведь у класса Singer базовый класс - это Worker, а не Waiter!
PM MAIL   Вверх
boostcoder
Дата 23.7.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(novice2011 @  23.7.2011,  17:08 Найти цитируемый пост)
но ведь у класса Singer базовый класс - это Worker, а не Waiter

а у Waiter`а какой базовый?  smile 
PM WWW   Вверх
borisbn
Дата 23.7.2011, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



novice2011, ссылка на Waiter преобразовывается к ссылке на Worker
Singer(const Worker & wk, int v = 0) <--- сюда идёт попытка "положить" Waiter'а. Он (Waiter) легко преобразовывается к Worker &

Код

class Base {};
class Deriv1 : public Base
{
public:
    Deriv1( const Base & b ) {}
};

class Deriv2 : public Base
{
public:
    Deriv2( const Base & b ) {}
};

Base bb;
Deriv1 d1( bb );
Deriv2 d2( d1 );
// предыдущая строка всё равно, что следующие
const Base & b = d1;
Deriv2 d2( b );


http://liveworkspace.org/code/f8ebe2ef0c09...5f057aac79d3d2e

Добавлено @ 17:21
Цитата(boostcoder @  23.7.2011,  16:33 Найти цитируемый пост)
очень жестокое наследование ты замутил  

поддерживаю... не представляю жизненной ситуации, где бы такое было бы самым простым/оптимальным/надёжным/понятным решением
разве что в boost ... шутка в отместку за кутю

Это сообщение отредактировал(а) borisbn - 23.7.2011, 17:25


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 23.7.2011, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(borisbn @  23.7.2011,  17:19 Найти цитируемый пост)
не представляю жизненной ситуации, где бы такое было бы самым простым/оптимальным/надёжным/понятным решением

никогда и нигде!

Цитата(borisbn @  23.7.2011,  17:19 Найти цитируемый пост)
разве что в boost

никогда не видел такого в бусте. буст преимущественно написан на шаблонах, по этому городить такое нет необходимости. статический полиморфизм и понятнее и быстрее работает, и позволяет выявить ошибки в compile-time.

up.
хотя это и не динамический. но жуть в любом случае..


Это сообщение отредактировал(а) boostcoder - 23.7.2011, 17:39
PM WWW   Вверх
novice2011
Дата 23.7.2011, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо большое, ребята,  за помощь. Этот код взят из книги Прата "Язык программирования C++, лекции и упражнения".
PM MAIL   Вверх
abv
Дата 25.7.2011, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я бы еще добавил, что в C++ любой конструктор, который принимает единственный аргумент (может быть и второй аргумент и т. д., но все они должны иметь значения по умолчанию), преобразует значение типа аргумента в тип класса. У вас конструктор Singer(const Waiter & wt, v)) имеет все необходимые для этого условия. Компилятор ищет конструктор Singer(const Waiter & wt, v) (здесь v имеет значение по умолчанию), но его нет, а есть Singer(const Worker & wk, int v = 0), который подходит для конструирования базовой части объекта.  Вот его-то и задействует конструктор Singer.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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