[c++] VS i Borland nie zgłasza błędów w kodzie, GCC zgłasza

0

Witam Wszystkich!

Zrobiłem mały programik w C++, który kompiluje się i działa w VS 2005 i w Borland Turbo C++ 2006. Chciałem dalej z nim pracować ale już na Linuksie, w Eclipse CDT. I tu problem. GCC zgłasza 2 błędy.
Opis pierwszego błędu:
Multiple markers at this line
-Line breakpoint: main.cpp [line: 62]
-błąd: no matching function for call to `matrix::matrix(matrix),

dotyczy on 62 linii kodu pliku main.cpp: C = B+B;

Opis drugiego błędu (ostrzeżenie):
uwaga: candidates are: matrix::matrix(matrix&)

dotyczy linii 16 w pliku matrix.h: matrix(matrix &);

Program robi podstawowe operacje na macierzach.
Projekt składa się z trzech plików (main.cpp, matrix.h, matrix.cpp), które zamieszczam poniżej.
Wszystko było OK do momentu przeładowania operatora+
Proszę o pomoc w wyjaśnieniu, dlaczego na Windowsie w VS i Borland program działa, a na Linuksie w Eclipse z GCC są błędy. Proszę też o wyrozumiałość - dopiero się uczę programować i chciałbym zrozumieć swój błąd.
Oto pliki składające się na mój projekt:

main.cpp:

#include"matrix.h"

int main(void)
{
	cout << "Witamy na pokladzie!" << endl;

	cout << "Tworze macierz A" << endl;
	matrix A;
	cout << "Tworze macierz B" << endl;
	matrix B(3,4);
	cout << "Drukuje macierz A" << endl;
	A.print();
	cout << "Drukuje macierz B" << endl;
	B.print();

	for(int r=1; r<=3; r++)
	{
		for(int c=1; c<=4; c++)
		{
			B.set(r, c, r+c);
		}
	}

	cout << "Drukuje macierz B" << endl;
	B.print();

	int tab[3][3]; //= {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };

	for(int i=0; i<3; i++)
	{
		for (int j=0; j<3; j++)
		{
			tab[i][j] = (i+ j);
		}
	}

	cout << "\n\tTABLICA" << endl;

	for (int i=0; i<3; i++)
	{
		for(int j=0; j<3; j++)
		{
			tab[i][j]= i+j;
			cout << tab[i][j];
		}
		cout << endl;
	}
	
	cout << "A=B" << endl << endl;
	A=B;
	cout << "Drukuje macierz A" << endl << endl;
	A.print();
	
	matrix X(2,2);
	A=X;
	cout << "\nA=X" << endl << endl;
	cout << "Drukuje macierz A" << endl << endl;
	A.print();
	
	matrix C;
	cout << "\nC=B+B+B+B" << endl << endl;
	C = B+B;
	cout << "Drukuje macierz C" << endl << endl;
	C.print();
	
}

matrix.h:

#include<iostream>
using namespace std;


class matrix
{
	int rows;
	int columns;
	float **wsk;

public:
	//------------------KONSTRUKTORY---------------

	matrix();	// konstruktor macierzy zerowej
	matrix(int, int);	// k. tworz. mac. wier. x kol.
	matrix(matrix &);	// k. kopiujacy
	matrix(float *, int, int);	// kopia z tablicy
	~matrix();

	//------------------FUNKCJE-----------------

	void set(int, int, float);	// zapisuje pod komórkę
	float get(int, int);			// zwraca z komórki
	void print();				// wypisuje elementy macierzy

	//----------------OPERATORY----------------------
	//void operator=(matrix);
	matrix & operator=(const matrix &);
	matrix operator+(matrix);
	
	
	

};

matrix.cpp

#include"matrix.h"

matrix::matrix()
{
	cout << "\t\t\t[ matrix() ]" << endl;
	rows = 0;
	columns = 0;
	wsk = 0;
}

matrix::matrix(int x, int y)
{
	cout << "\t\t\t[ matrix(int, int) ]" << endl;
	rows = x;
	columns = y;

	wsk = new float * [rows];

	for (int i=0; i<rows; i++)
	{
		wsk[i] = new float [columns];
	}

	for (int i=0; i<rows; i++)
	{
		for(int j=0; j<columns; j++)
		{
			wsk[i][j]=0;
		}
	}
}

matrix::matrix(matrix & source)
{
	cout << "\t\t\t[ matrix(matrix &) ]" << endl;
	rows = source.rows;
	columns = source.columns;

	wsk = new float *[rows];

	for (int i=0; i<rows; i++)
	{
		wsk[i] = new float [columns];
	}

	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<columns; j++)
		{
			wsk[i][j] = source.wsk[i][j];
		}
	}
}

matrix::matrix(float *tab, int x, int y)
{
	rows = x;
	columns = y;

	wsk = new float * [rows];
	for (int i=0; i<columns; i++)
	{
		wsk[i] = new float[columns];
	}

	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<columns; j++)
		{
			wsk[i][j]= *(tab+ x*i +j);
		}
	}
}

matrix::~matrix()
{
	cout << "\t\t\t[ DESTRUKTOR ]" << endl;
	for(int i=0; i<rows; i++)
		{
			delete [] wsk [i];
		}

	delete [] wsk;
}
//-----------------------------Funkcje---------------

void matrix::set(int r, int c, float var)
{
	cout << "\t\t\t[ set ]" << endl;
	wsk[r-1][c-1] = var;
}

float matrix::get(int r, int c)
{
	cout << "\t\t\t[ get ]" << endl;
	return wsk[r-1][c-1];
}

void matrix::print()
{
	cout << "\t\t\t[ print ]" << endl;
	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<columns; j++)
		{
			cout << wsk[i][j] << "\t";		}
		cout << endl;
	}
}


//-------------PRZELADOWANE OPERATORY----------------------

matrix & matrix::operator=(const matrix & wzor)
{
	cout << "\t\t\t\t\t\t\t\t\t\t[ OPERATOR= ]" << endl;
	if (&wzor == this) return *this; // Sprawdzam czy nie kopiuje sam siebie
	else
	{
		this->~matrix();		// kasuję starš zawartoć

		//	kopiuję zawartoć:

		rows = wzor.rows;
		columns = wzor.columns;

		wsk = new float *[rows];

		for (int i=0; i<rows; i++)
		{
			wsk[i] = new float [columns];
		}

		for(int i=0; i<rows; i++)
		{
			for(int j=0; j<columns; j++)
			{
				wsk[i][j] = wzor.wsk[i][j];
			}
		}
		return *this; // operator przypisania zwraca referencję obiektu swojej klasy !!!!!!
	}
}

//---------------------------------------------------------------------------------

matrix matrix::operator+ (matrix x)
{
	cout << endl << "\t\t\t\t\t\t\t\t\t\t[ OPERATOR+ ]\n";
	if(x.rows == this->rows && x.columns == this->columns)
	{
		matrix z(x.rows, x.columns);
		for(int i=0; i<x.rows; i++)
		{
			for(int j=0; j<x.columns; j++)
			{
				z.wsk[i][j] = wsk[i][j] + x.wsk[i][j];
			}
		}
		return z;
	}

	else
	{
		cout << "NIEZGODNOSC WYMIAROW" << endl << endl;
		matrix M;
		return M;
	}
}
0

Z jakiegoś powodu konstruktor kopiujący w gcc musi mieć const:

matrix::matrix(const matrix & source)
{
    ....
0

Bardzo dziękuję za pomoc. Problem rzeczywiście znika. Nie wiem tylko dlaczego GCC wymaga const w konstruktorze kopiującym - przecież jest to 'zabezpieczenie' z którego nie muszę korzystać.

0

Może dlatego, że taki właśnie konstruktor kopiujący ma być?

0

Taki powinien oczywiście być. Ale standard języka C++ nie narzuca takiego obowiązku.

0
boaxdr napisał(a)

Taki powinien oczywiście być. Ale standard języka C++ nie narzuca takiego obowiązku.
Dokładnie! Przykład: auto_ptr, gdzie konstruktor kopiujący NIE MOŻE mieć const. Co ciekawe po zajrzeniu do nagłówka memory i odnalezieniu auto_ptr const nie ma, a konstruktor kopiujący działa, co wskazuje na pewną niekonsekwencje ze strony gcc.

0

a moze problem tkwi gdzies indziej? copyctor auto_ptr jest wywolywany (zwykle) jawnie i zawsze ma argumenty nonconst, zas tutaj B=C+C copyctor jest wywolywany niejawnie, tyczy sie obiektu TYMCZASOWEGO i ten tymczasowy obiekt najwyrazniej jest const i dlatego nie moglo znalezc pasujacego copyctora

0

sorry, ale się z tobą nie zgadzam.
Łatwo mi sobie wyobrazić sytuację, w której poniższy kod miałby uzasadnienie:

class T
{
private:
    T( int arg );

public:
     static auto_ptr<T> New( int argument )
     {
          return auto_ptr<T>( new T( argument ) );
     }
...
private:
    
...
};

a tu przy użyciu metody T:New zostanie niejawnie wywołany copy-konstruktor.

0

to prawda. to co mialem na mysli, to to, ze w tamtym konkretnym miejscu tymczasowa automatyczna kopia mogla byc uwazana za const i stad blad kompilacji..

1 użytkowników online, w tym zalogowanych: 0, gości: 1