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

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

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

Проблема:нужно сделать конструкторы: один-по умолчанию, а другой- с параметром(и).
У меня есть и он по умолчанию, но в нем делается ввод матрицы, а так нельзя. Как закинуть ввод в другой конструктор с парамером(и)?

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

class matrix
{ 
private:
        int m,n;
        int **matrica;
public: 
        matrix();
        ~matrix(); 
        int get(int ,int);
        void print();
		void setSize();
};
 void matrix::setSize()
{
    int first;
    int second;
    cout<<"Enter first size: ";
    cin>>first;
    cout<<"Enter second size: ";
    cin>>second;
    n=first;
    m=second;
	system("cls");
 }

matrix::matrix()
{  
	setSize();
        
	matrica=new int*[n];
       for (int i = 0; i < n; i++)
                matrica[i] = new int[m];
				
        for ( int i = 0; i < n; i++)
               for (int j = 0; j < m; j++)
                        matrica[i][j] = rand() % 10;
 }
void matrix: :p rint()
{
     for(int i = 0; i < n; i++)
     {
         for(int j = 0; j < m; j++)
               cout<<matrica[i][j]<<' ';
         cout<<"\n";
     }
 
}
 matrix::~matrix()
{
     for (int i = 0; i < n; i++)
     free(matrica[i]);
free(matrica);
}
int matrix::get(int i,int j)
{
         if(i>=n||j>=m)
            return 0;
         cout<<matrica[i][j]<<'\n';
}
 
int main ()
{  
        system("cls");
        matrix object;
        object.print();
        int i, j;
        cout<<"\n get (i.j):"<<endl;
        cout<<"Enter i: ";
        cin>>i;
        cout<<"Enter j: ";
        cin>>j;
        if(object.get(i,j)==0)
           cout<<"i or j more or equal than n or m!\n";
        system("PAUSE");
        return 0;
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Правильный подход будет следующим:

- Вынести код, считывающий данные с клавиатуры из класса matrix наружу;
- В классе matrix сделать конструктор, принимающий все данные, необходимые для построения матрицы;
- Дефолтный конструктор должен быть удалён: он никак не вписывается в идеологию, так как дефолтной матрицы не бывает.

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

Почему после завершения работы вылазит ошибка?

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

class matrix
{ 
private:
        int m,n;
        int **matrica;
public: 
         matrix();
		 matrix(int);
        ~matrix(); 
		 matrix(const matrix &A1);
        int get(int ,int);
        void print();
		void setSize();
};
matrix::matrix()
{
	int a;
	n=m=a=0;
}
void matrix::setSize()
{
    int first;
    int second;
    cout<<"Enter first size: ";
    cin>>first;
    cout<<"Enter second size: ";
    cin>>second;
    n=first;
    m=second;
	system("cls");
 }

matrix::matrix(int b)
{  
	setSize();

int **matrica2=(int**)malloc(n*sizeof(int*));
for(int i=0;i<n;i++)
    matrica2[i]=(int*)malloc(m*sizeof(int));

        for (int i = 0; i < n; i++)
               for (int j = 0; j < m; j++)
                        matrica2[i][j] = rand() % 10;
matrica=matrica2;
 }
void matrix: :p rint()
{
     for(int i = 0; i < n; i++)
     {
         for(int j = 0; j < m; j++)
               cout<<matrica[i][j]<<' ';
         cout<<"\n";
     }
}

 matrix::~matrix()
{
	
     for (int i = 0; i < n; i++)
     free(matrica[i]);
free(matrica);
}

int matrix::get(int i,int j)
{
         if(i>=n||j>=m)
            return 0;
         cout<<matrica[i][j]<<'\n';
	
}

matrix::matrix(const matrix &A1)
{
	n=A1.n;
	int **matrica2=(int**)malloc(n*sizeof(int*));
	for(int i=0;i<n;i++)
		matrica2[i]=(int*)malloc(m*sizeof(int));

	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			matrica2[i][j]=A1.matrica[i][j];
}

int main ()
{  
        system("cls");
        matrix object;
		matrix ob(5);
		object=ob;
        object.print();
        int i, j;
        cout<<"\n get (i.j):"<<endl;
        cout<<"Enter i: ";
        cin>>i;
        cout<<"Enter j: ";
        cin>>j;
        if(object.get(i,j)==0)
           cout<<"i or j more or equal than n or m!\n";
        system("PAUSE");
        return 0;
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Потому, что для класса не создан оператор присваивания. В строке

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

object=ob;
происходит побитовое копирование объекта, который содержит поинтер. В конце программы происходит вызов деструктора для первого объекта, в котором удаляется память по поинтеру. Затем происходит вызов деструктора для второго объекта, что приводит к попытке удалить уже удалённую память - отсюда краш.

Предыдущий пост я писал зря, как я понял - никаких изменений :)

P.S. Евгений Александрович, когда научишься использовать правильный BB таг для выделения C++ кода? Я уже устал поправлять твои сообщения.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

А нельзя ли разрешить эту проблему конструктором копирования , мне его нужно по условию использовать. Как заставить его работать?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Чтобы отработал конструктор копирования, следует вот этот код:

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

matrix object;
matrix ob(5);
object=ob;
Заменить на такой:

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

matrix ob(5);
matrix object(ob);
А вообще подход: "Давайте поменяем вызывающий код, так как, чтобы всё заработало, а то тут краш во внутреннем код" неправильный в корне. Если во внутреннем коде есть проблема - она должны быть устранена. Ты, как создатель класса matrix, обязан обеспечить правильное функционирование класса при любом, даже самом дурацком его использовании. То, что не должно работать - должно быть запрещено. То что должно работать - обязано работать корректно. И вообще, если для класса переписывается конструктор копирования, то оператор присваивания должен быть переписан обязательно! Он должен быть либо правильно имплементирован и размещён в public секции, либо быть пустым и спрятан в приватной (если ты хочешь запретить присваивания).
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Евгений Александрович
Сообщения: 82
Зарегистрирован: 19 дек 2009, 16:48

спасибо за внимание. Разобрался с этим конструктором :) нужно было вот так:

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

 n = a.n;
    m = a.m;
        matrica = (int**)malloc( n * sizeof(int*) );
        for( int i = 0; i < n; ++i )
                matrica[i] = (int*)malloc( m * sizeof(int) );
        for( int i = 0; i < n; ++i )
                for( int j = 0; j < m; ++j )
                        matrica[i][j] = a.matrica[i][j];
P.S.
P.S. Евгений Александрович, когда научишься использовать правильный BB таг для выделения C++ кода? Я уже устал поправлять твои сообщения.

Объясните пошогово как это делать :)
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

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

Проблема: выводит ерунду, что не так?

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

 
class bank
{	
private:
	char bank_name[44];
	char name[44];
	int value;
public:
	bank(){}
	bank(char *,char *,int);
	void show();
};
int n,m;
bank::bank(char *_bank_name,char *_name,int _value)
{
	cout<<" input _name of bank:"<<endl;
	cin>>_bank_name;
	strcpy(bank_name,_bank_name);
	cout<<" how mach persons:"<<endl;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cout<<" input person:"<<endl;
		cin>>_name;
		strcpy(name,_name);

		cout<<"input value:"<<endl;
		cin>>_value;
		value=_value;
		
	}
}
void bank::show()
{
	cout<<bank_name<<endl;
}
void main()
{
	bank object;
	bank ob;
	ob.show();
	system("PAUSE");
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Конструктор по умолчанию не инициализирует член класса bank_name, который ты впоследствии выводишь в методе show. По той причине, что объект класса был создан на стеке, вся память, в которой он расположен забита мусором. Исправить проблему можно написав следующее:

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

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