Страница 4 из 4

Re: конструкторы

Добавлено: 24 сен 2010, 21:58
Romeo
Почему вызовы delete располагаются в методе show? Они должны быть в деструкторе! При текущем положении дел метод show вызвать больше одного раза нельзя, а это неправильно.

Re: конструкторы

Добавлено: 27 сен 2010, 21:43
Евгений Александрович
Проблема: при выводе данных( а в частности проблема с выводом полей "value") то обрезаются данные, то заполняются лишними(в зависимости от ввода vc);
Т.е. нормально работает, если только первый размер(за размерность отвечает vc) = вотрому размеру.

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

class bank
{   
private:
	char *bank_name;
	char **name;
	int **value;
	int **salary;
public:
	bank(){}
	void add(int );
	void show(int );
};
int vc;
void bank::add(int n)
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
	cin>>bank_name;

	char str[55];
	name=new char *[n];
	value=new int *[n];
	salary=new int *[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);

	cout<<"input amount of values:";
cin>>vc;
value[i]=new int[vc];
salary[i]=new int[vc];
for(int j=0;j<vc;j++)
{
	cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
}
system("cls");
}
void bank::show(int n)
{
	cout<<bank_name<<endl;
	for(int i=0;i<n;i++)
	{
	cout<<name[i]<<"\n";
	for(int j=0;j<vc;j++)
	{
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
	}
	}
}

void main()
{
	char **name='\0',*bank_name='\0';int *value=0;
	int n;
	bank object;
	cout<<" size (n):"<<endl;
	cin>>n;
	bank obj;
	obj.add(n);
	obj.show(n);
	system("PAUSE");
	delete []name;
	delete []bank_name;
	delete []value;
}

Re: конструкторы

Добавлено: 27 сен 2010, 22:40
Romeo
Слушай, я просто поражаюсь, как ты умудряешься сделать всё максимально неправильно.

1. Что это первая строка в main? Зачем нужны эти переменные?
2. Зачем делать этим переменных в конце delete, если ты им ни разу не делал new?
3. Зачем n хранить снаружи и передавать как в метод add, так и в метод show, что вообще является ужасным. Объект сам должен знать сколько в нём элементов: n сама просится быть внесённой в класс, в качестве поля, неужели это не очвидно?
4. Куда дела деструктор класс bank. Я уже писал о деструкторе 3 раза. В нём должна удаляться память. Где он?

Re: конструкторы

Добавлено: 27 сен 2010, 23:39
Евгений Александрович
Сделал по вашим советам. Появилась проблема: ввожу размерность n - все норм, а вот уже после ввода имени банка - ошибка(debug library). Что ж опять то не так?

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

class bank
{   
private:
	char *bank_name;
	char **name;
	int **value;
	int **salary;
public:
	int n;
	bank(){}
	~bank();
	void add( );
	void show( );
};
int vc;
void bank::add()
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
	cin>>bank_name;

	char str[55];
	name=new char *[n];
	value=new int *[n];
	salary=new int *[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);

	cout<<"input amount of values:";
cin>>vc;
value[i]=new int[vc];
salary[i]=new int[vc];
for(int j=0;j<vc;j++)
{
	cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
}
system("cls");
}
void bank::show()
{
	cout<<bank_name<<endl;
	for(int i=0;i<n;i++)
	{
	cout<<name[i]<<"\n";
	for(int j=0;j<vc;j++)
	{
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
	}
	}
}
bank::~bank()
{
	delete []name;
	delete []bank_name;
	delete []value;
}
void main()
{
	int n;
	bank object;
	cout<<" size (n):"<<endl;
	cin>>n;
	bank obj;
	obj.add();
	obj.show();
	system("PAUSE");
}

Re: конструкторы

Добавлено: 28 сен 2010, 08:53
Romeo
Ты n сделал поле класса, но нигде его не проставляешь. Этот код не должен работать. Неужели работает? :) Ты хоть раз запускал его?

Раньше у тебя был дефолтный конструктор реализован. Где он сейчас делся?

Re: конструкторы

Добавлено: 28 сен 2010, 18:02
Евгений Александрович
Заработало, но возникла проблема: выводит еще какое-то лишнее число если размерность value одного человека не совпадает с размерностью другого.

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

class bank
{   
private:
	char *bank_name;
	char **name;
	int **value;
	int **salary;
public:
	int n;
	bank();
	~bank();
	void add( );
	void show( );
	void setsize();
};
int vc;
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::add()
{
    bank_name=new char[33];
    cout<<"input bank_name\n"<<endl;
	cin>>bank_name;

	char str[55];
	name=new char *[n];
	value=new int *[n];
	salary=new int *[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);

	cout<<"input amount of values:";
cin>>vc;
value[i]=new int[vc];
salary[i]=new int[vc];
for(int j=0;j<vc;j++)
{
	cout<<"values:"<<j<<endl;
cin>>value[i][j];
cout<<"salary:"<<endl;
cin>>salary[i][j];
}
}
system("cls");
}
void bank::show()
{
	cout<<bank_name<<endl;
	for(int i=0;i<n;i++)
	{
	cout<<name[i]<<"\n";
	for(int j=0;j<vc;j++)
	{
   cout<<value[i][j]<<" "<<salary[i][j]<<endl;
	}
	}
}
bank::~bank()
{
	delete []name;
	delete []bank_name;
	delete []value;
	delete []salary;
}
void main()
{
	bank obj;
	obj.setsize();
	obj.add();
	obj.show();
	system("PAUSE");
}

Re: конструкторы

Добавлено: 28 сен 2010, 22:29
Romeo
Уже лучше. Осталась одна проблема - именно та, которую ты описал. А источник её - глобальная переменная vc. Из-за того, что она глобальная, переменная переписывается при каждом новом вызове cin<<vc и под конец выполнения add содержит самое последнее значение amount. С другой стороны, в методе show использует снова эта же самая переменная, поэтому для всех клиентов будут выводится количество value такое, как было у последнего клиента, а это ошибка, ведь количество value у каждого клиента своё и поэтому ты будешь залезать в "чужую" память, если количество предыдущих value меньше, либо просто недовыводить все value, если количество предыдущих value больше.

Исправляется ошибка просто. Глобальную переменную vс нужно уничтожить. Её должно заменить поле класса например с тем же именем vc типа - массив int'ов, которое будет хранить количество values для каждого клиента. В методе add нужно выделять под этот массив n элементов, затем i-й элемент считывать из потока. Также нужно поменять все циклы, которые бегут до vc, чтобы они бежали до vc. Ну и в конце не забыть удалить выделенную под vc память в деструкторе класса.

Вот и вся премудрость :)

Re: конструкторы

Добавлено: 28 сен 2010, 23:16
Евгений Александрович
Огромное спасибо Вам, идеально заработало. Не так то просто было.