Дружественные классы

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

Снова класс банк... Нужно его реализовать через 3 класса, а не через один :(
Проблема: не видны в main методы дружественных классов. И как заставить всё друг с другом взаимодействовать?

Код: Выделить всё

class person_name;
class person_value;
class bank
{   
private:
	char *bank_name;
public:
	int n,*vc;
	bank();
	~bank();
	void setsize();
    void addBank_name();
	void showBank();
	friend class person_name;
	friend class person_value;
};
class person_name
{
private:
	char **name;
public:
    void addName();
};

class person_value
{
private:
int **value;
int **salary;
public:
	void addValue();
};

bank::bank()
{
	 n=0;
	 int **value=0,**salary=0;
	 char **name='\0',*bank_name='\0';
}

void bank::setsize()
{
	cout<<" size (n):"<<endl;
	cin>>n;
}

void bank::addBank_name()
{
	bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
	cin>>bank_name;
}

void person_name::addName()
{
	char str[55];
	name=new char *[n];

for(int i=0;i<n;i++)
{
	system("cls");
	cout<<i<<":iput name:\n"<<endl;
	cin>>str;
	name[i]=new char[strlen(str)+1];
	strcpy(name[i],str);
}
}
void person_value::addValue()
{
	value=new int *[n];
	salary=new int *[n];
	vc=new int[n];
	for(int i=0;i<n;i++)
	{
	cout<<"input amount of values:";
cin>>vc[i];
value[i]=new int[n];
salary[i]=new int[n];
for(int j=0;j<vc[i];j++)
{
	cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
	}
system("cls");
}
void bank::showBank()
{
	cout<<bank_name<<endl;
	for(int i=0;i<n;i++)
	{
	cout<<name[i]<<"\n";
	for(int j=0;j<vc[i];j++)
	{
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
	}
	}
}
bank::~bank()
{
	delete []bank_name;
	delete []name;
	delete []value;
	delete []salary;
	delete []vc;
}
void main()
{
	bank object;
	object.addBank_name();
	object.setsize();
	object.showBank();
	system("pause");
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Код у тебя сейчас не компилируется в принципе. Ты разнёс объявления, а код, который использует поля - не исправил. И, кстати, снова ты неправильно всё делаешь. Данные неправильно разнёс. Класс bank должен содержать имя банка, массив объектов класса person и их количество (итого три поля). Класс person должен содержать имя персоны, массив объектов класса person_value и количество values (итого три поля). Класс person_value должен содержать два int поля: value и salary. Как-то так:

Код: Выделить всё

class person_value
{
   int m_nValue;
   int m_nSalary;
public:
   // constructor, destructor, methods
};

class person
{
   char* m_szName;
   person_value* m_values;
   int m_nValueCount;
public:
   // constructor, destructor, methods
};

class bank
{
   char* m_szName;
   person* m_persons;
   int m_nPersonCount;
public:
   // constructor, destructor, methods
};
О фрэндах забудь! Они разрушают инкапсуляцию. Обеспечивай доступ к закрытым полям через сеттеры и геттеры.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

О фрэндах забудь!
Мне, к сожеланию, пока только ими можно.
Вы меня озадачили вашим вариантром.Чувствую, что Вы правильно написали но не могу прочувствовать реализацию. Почему, например, у каждого класса свой счетчик? Для чего классу
person_value 2 инт поля?
А вот если добавить в банк массив имен,valus and salary - код начал работать.

Код: Выделить всё

class person_name;
class person_value;
class bank
{   
private:
	char *bank_name;
	char **name;
	int **value;
    int **salary;
public:
	int n,*vc;
	bank();
	~bank();
	void setsize();
    void addBank_name();
	void addName();
	void addValue();
	void showBank();
	friend class person_name;
	friend class person_value;
};
class person_name
{
private:
	char **name;
public:
	friend void bank::addName();
};

class person_value
{
private:
int **value;
int **salary;
public:
	friend void bank::addValue();
};
bank::bank()
{
	 n=0;
	 int **value=0,**salary=0;
	 char **name='\0',*bank_name='\0';
}

void bank::setsize()
{
	cout<<" size (n):"<<endl;
	cin>>n;
}

void bank::addBank_name()
{
	bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
	cin>>bank_name;
}

void bank::addName()
{
	char str[55];
	name=new char *[n];

for(int i=0;i<n;i++)
{
	system("cls");
	cout<<i<<":iput name:\n"<<endl;
	cin>>str;
	name[i]=new char[strlen(str)+1];
	strcpy(name[i],str);
}
}
void bank::addValue()
{
	system("cls");
	value=new int *[n];
	salary=new int *[n];
	vc=new int[n];
	for(int i=0;i<n;i++)
	{
		cout<<name[i]<<endl;
	cout<<"input amount of values:";
cin>>vc[i];
value[i]=new int[n];
salary[i]=new int[n];
for(int j=0;j<vc[i];j++)
{
	cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
	}
system("cls");
}
void bank::showBank()
{
	cout<<bank_name<<endl;
	for(int i=0;i<n;i++)
	{
	cout<<name[i]<<"\n";
	for(int j=0;j<vc[i];j++)
	{
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
	}
	}
}
bank::~bank()
{
	delete []bank_name;
	delete []name;
	delete []value;
	delete []salary;
	delete []vc;
}
void main()
{
	bank object;
	object.addBank_name();
	object.setsize();
	object.addName();
	object.addValue();
	object.showBank();
	system("pause");
}
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Евгений Александрович писал(а):А вот если добавить в банк массив имен,valus and salary - код начал работать.
Зачем в таком случае вообще нужны классы person_name и person_value, если они в коде вообще нигде не используются? :)
Собственно, насколько я понимаю, все в итоге вернулось на круги своя.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Полностью поддерживаю BBB. При таком подходе дополнительные классы не нужны вообще, ведь разнесение данных не произошло.

Далее по вопросам.
Евгений Александрович писал(а):Почему, например, у каждого класса свой счетчик?
m_nPersonCount - это то, что раньше было n.
m_nValueCount - это то, что раньше было vc.
Евгений Александрович писал(а):Для чего классу person_value 2 инт поля?
Потому, что в исходном варианте было два массива:
int **value;
int **salary;
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

Нучну делать постепенно по вашему примеру.
Начал расписывать класс person. Так ли я за него взялся?
И вопроыс: 1.
person_value* m_values;
что это такое и вообще для чего это, как это применяют?
2.
int m_nValueCount;
т.е. это ,думаю, для того, чтобы в классе person вводить value and salary или как?

Код: Выделить всё

class person
{
   char* m_szName;
   person_value* m_values;
   int m_nValueCount;
public:
  person();
  ~person();
  void addName();
};
реализация:

Код: Выделить всё

person: :p erson()
{

	char **name='\0';
}
person::addName()
{
	name=new char *[m_nPersonCount];
	char str[33];
	for( int i=0;i<m_nPersonCount;i++)
	{
		cout<<" input name:"<<endl;
	    cin>>str;
		name[i]=new char [strlen(str)+1];
		strcpy(name[i],str);
	}
}
person::~person()
{
	for(int i=0;i<n;i++)
	delete []name[i];
	delete []name;
}
BulldozerBSG
Сообщения: 270
Зарегистрирован: 09 янв 2010, 04:14
Контактная информация:

Я так понимаю это лабораторная работа или что то типа того. Как звучит полное задание?
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

Все просто: есть класс банк. в банке-сотрудники. у сотрудников свои счета ,а на них - суммы денег. В одном то классе у меня все работает, но мне нужно на 3 разбить. Romeo, за что ему большое спс, подсказал в сообщении №2 как это должно выглядеть.И вот постепенно пытаюсь это реализовать(сообщении №6). Правильно ли я начал делать? :)
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

По поводу вопросов.
Вопрос №1: person_value* m_values - это массив персон. В банке может быть много клиентов, правильно ведь?
Вопрос №2: int m_nValueCount - это количество счётов у отдельно взятой персоны.

Правильно ли начал делать? Нет, неправильно.

1. У класса person нету char** name. У клиента банка есть только одно имя, а не целый массив имён! Согласись, что это логично.
2. Поле m_nPersonCount расположено в классе bank, а не в классе person. Не понимаю, почему оно фигурирует в коде класса person.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Оооо, наконец-то озвучена постановка задачи! Я тогда возьму на себя смелость обозвать всё своими именами:

Код: Выделить всё

// класс хранит информацию о счёте
class CAccount
{
public:
   CAccount();
   ~CAccount();

   void InputData();
   void OutputData();

private:
   int m_nID; // идентификатор счёта
   int m_nValue; // количество денег на счёту
};

// класс хранит информацию о клиенте банка
class CClient
{
public:
   CClient();
   ~CClient();

   void InputData();
   void OutputData();

private:
   char* m_szName; // имя клиента
   CAccount* m_pAccounts; // счета данного клиента
   int m_nAccountCount; // количество счетов
};

// класс хранит информацию о банке
class CBank
{
public:
   CBank();
   ~CBank();

   void InputData();
   void OutputData();

private:
   char* szName; // имя банка
   CClient* m_pClients; // клиенты данного банка
   int m_nClientCount; // количество клиентов
}
Давай теперь вместе реализовывать методы классов. Чтобы ты понял как это будет выглядеть, привожу реализацию методов класса CAccount. Это самый просто класс, так что я тебе не очень сильно помогу :)

Код: Выделить всё

CAccount::CAccount() : m_nID(-1), m_nValue(-1) {}

CAccount::~CAccount() {}

void CAccount::InputData()
{
   cout << "Enter account ID: ";
   cin >> m_nID;
   cout << "Enter account value: ";
   cin >> m_nValue;
}

void CAccount::OutputData()
{
   cout << "Accout ID: " << m_nID << ", Account Value: " <<  m_nValue << endl;
}
Теперь твоя очередь писать код, а я буду его критиковать, уж извини. Первое твоё задание - написать методы класса CClient, а именно конструктор, деструктор и его InputData (метод InputData у каждого класса свой, как ты уже заметил). Вот список того, что должен делать метод InputData:

- вывесте приглашение и считать имя клиента.
- вывести приглашение и считать количество счетов у клиента.
- выделить память под массив m_pAccounts, указав в качестве количества элементов количество полученное на предыдущем шаге.
- в цикле, который будет повторятся столько раз, сколько у клиента счетов делать
{
- вывести сообщение, что вводится информация i-го счёта
- для i-го элемента массива вызывать метод InputData
}

По аналогичной схеме реализовывается OutputData.

Как только справишься с этим заданием, приступим к имплементации класса CBank :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить