Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.04.2010, 17:09   #1
terminadoor
Пользователь
 
Регистрация: 26.06.2008
Сообщений: 86
По умолчанию Mножественное наследование

Здраствуйте. Столкнулся со следующей проблемой. У меня есть 4 класы: человек (person) ,студент - student,работник - employer, студент-работник - student_employer. Клас студент-работник наследует классы студент и работник. Классы студент и работник наследуют класс человек, что приводит к тому, что у меня в класе студент-работник два раза дублируются поля класса человек. Как мне убрать дублирование? Вот мой код:

PHP код:
#include <iostream>
#include <string>
using namespace std;
virtual class Person{
protected:
    
string first;
    
string second;
public: 
    
friend istream operator>>(istream &inPerson &p){
        
in>>p.first>>p.second;
        return 
in;
    }
};
class 
Employer:public virtual Person{
protected:
    
string status;
public:
    
friend istream operator>>(istream &inEmployer p){
        
in>>(Person&)p>>p.status;
        return 
in;
    }
};
class 
Student: public virtual Person{
protected:
    
int course;
public:
    
friend istream operator>>(istreamin,Student &s){
        
in>>(Person&)s>>s.course;
        return 
in;
    }
};
class 
Student_Employer:public virtual Student,public virtual Employer{
protected:
    
int grad;
public:
friend istream operator>>(istream &in,Student_Employer s){
        
in>>(Student&)s>>(Employer&)s>>s.grad;
        return 
in;
    }
};
void main(){
Student_Employer T;
cin>>T;

Вместо 5 полей считивается 7!.

P.S. Также у меня нет на форуме кнопки для подсветки кода С++.

Буду благодарен за ответы и обьяснения.
TerMinAdoOR
terminadoor вне форума Ответить с цитированием
Старый 19.04.2010, 18:31   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

сначала по твоему коду:

Код:
#include <iostream>
#include <string>
using namespace std;
virtual class Person{
protected:
    string first;
    string second;
public: 
    friend istream & operator>>(istream &in, Person &p){
        in>>p.first>>p.second;
        return in;
    }
};
class Employer:public virtual Person{
protected:
    string status;
public:
    friend istream & operator>>(istream &in, Employer& p){
        in>>(Person&)p>>p.status;
        return in;
    }
};
class Student: public virtual Person{
protected:
    int course;
public:
    friend istream & operator>>(istream& in,Student &s){
        in>>(Person&)s>>s.course;
        return in;
    }
};
class Student_Employer:public virtual Student,public virtual Employer{
protected:
    int grad;
public:
friend istream & operator>>(istream &in,Student_Employer& s){
        in>>(Student&)s>>(Employer&)s>>s.grad;
        return in;
    }
};
void main(){
Student_Employer T;
cin>>T;
}
красное - удалить, зеленое - добавить.
почему вводится 7 полей думаю понятно. т.к ты наследуешься от Person виртуально, классы Student и Employer имеют общую копию Person. при вводе Student_Employer сначала вызываешь заполнение Student (который вызывает заполнение Person), потом вызываешь заполнение Employer (который повторно вызывает заполнение Person).
по-хорошему я бы отказался от дружественных функций и нисходящего преобразования в пользу виртуальных функций. и кстати, для нисходящего преобразования лучше используй static_cast. если не менять особо код я вижу один выход:

Код:
#include <iostream>
#include <string>

using namespace std;

//------------------------------------------------------------------------------
class Person {
public:
	Person() : init(false)
	{}

	inline bool IsInit()
	{ return init; }

	void make_init(istream &in)
	{
		in >> first >> second;
		init = true;
	}

	friend istream& operator>>(istream &in, Person &p)
	{
		if (!p.IsInit())
			p.make_init(in);
		return in;
	}

protected:
	string first;
	string second;

private:
	bool init;
};

//------------------------------------------------------------------------------
class Employer : virtual public Person {
public:
	friend istream& operator>>(istream &in, Employer &p)
	{
		in >> static_cast<Person&>(p) >> p.status;
		return in;
	}

protected:
	string status;
};

//------------------------------------------------------------------------------
class Student: virtual public Person {
public:
	friend istream& operator>>(istream& in, Student &s)
	{
		in >> static_cast<Person&>(s) >> s.course;
		return in;
	}

protected:
	int course;
};

//------------------------------------------------------------------------------
class Student_Employer : public Student, public Employer {
public:
	friend istream &operator>>(istream &in, Student_Employer &s)
	{
		in >> static_cast<Student&>(s) >> static_cast<Employer&>(s) >> s.grad;
		return in;
	}

protected:
	int grad;
};

//------------------------------------------------------------------------------
void main()
{
	Student_Employer T;
	cin >> T;
}
чтоб предотвратить повторную перезапись полей класса Person.
ну либо в каждом классе сделать свой ввод
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 19.04.2010 в 18:42.
pproger вне форума Ответить с цитированием
Старый 19.04.2010, 18:54   #3
terminadoor
Пользователь
 
Регистрация: 26.06.2008
Сообщений: 86
По умолчанию

Можешь поподробней как сдеать в каждом классе свой ввод без дублирования?
TerMinAdoOR
terminadoor вне форума Ответить с цитированием
Старый 19.04.2010, 18:57   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

Код:
	friend istream &operator>>(istream &in, Student_Employer &s)
	{
		in >> s.first >> s.second >> s.course >> s.status >> s.grad;
		return in;
	}
и т.п.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Наследование Сергей089 Помощь студентам 6 07.02.2010 12:04
Наследование lolopolosko Помощь студентам 1 21.11.2009 17:17
Наследование на C++ dziga1989 Помощь студентам 5 22.10.2009 11:25
Наследование z3rg Общие вопросы C/C++ 9 30.04.2009 20:43
Наследование Кирилл13 Общие вопросы C/C++ 1 11.11.2008 14:47