operator-problem i C++ [-- Löst! --]

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

operator-problem i C++ [-- Löst! --]

Inlägg av arvidb »

Jag har definierat en operator+ för en matrisklass som jag har skrivit, men kompilatorn klagar när jag försöker använda operatorn. Vad gör jag för fel?

Kod: Markera allt

my:~/cprog06/lab1ex12>g++ -Wall -o test matrix_test.cpp matrix.cpp ../lab14/vector.cpp
matrix_test.cpp: In function 'int main()':
matrix_test.cpp:41: error: no matching function for call to 'Matrix::Matrix(Matrix)'
matrix.h:16: note: candidates are: Matrix::Matrix(Matrix&)
Deklaration av operatorn (medlemsmetod i Matrix):

Kod: Markera allt

Matrix operator+(const Matrix &) const;
matrix_test.cpp:41:

Kod: Markera allt

std::cout << "m1 + m2: \n" << m1 + m2 << "\n";
operator+ tar ju en referens, så varför i hela friden vill kompilatorn ha en konstruktor, och dessutom prompt en copykonstruktor som tar ett objekt, och inte en referens?

Arvid
Senast redigerad av arvidb 9 november 2006, 13:42:19, redigerad totalt 1 gång.
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

Eftersom den returnerar en Matrix, måste du inte definera operatorn << om du ska skriva ut den med cout? Men det kanske du redan har.
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Jodå, utskriftsoperatorn är definierad, implementerad och testad. :)

Arvid
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

Jag tror inte att den kan vara en medlemsfunktion. Följande fungerar.

Kod: Markera allt

#include <iostream>
using namespace std;

class test {
	friend ostream &operator<<(ostream &o, const test &t);

	private:
		int var;

	public:
		test(int val);
		int operator+(const test &b);
};

test::test(int val) {
	var = val;
}

int test::operator+(const test &b)  {
	return var+b.var;
}


ostream &operator<<(ostream &o, const test &t)  {
	cout << t.var;
	return o;
}

int main() {
	test a(3), b(2);

	cout << a+b;
}
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Nu förstår jag inte riktigt; test::operator+ är ju en medlemsfunktion i klassen test?

Jag har i vart fall testat att deklarera den som en icke-medlemsfunktion:

Kod: Markera allt

class Matrix
{
  ...
};

Matrix operator+(const Matrix &, const Matrix &);
men får exakt samma felmeddelande. Har även testat att anropa med

Kod: Markera allt

m1.operator+(m2)
- samma fel igen.

Arvid
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

Nä jag förstår inte heller hur jag tänkte :wacko:
Om du postar lite mer kod kanske det blir lättare att se ev. fel.
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Det kanske är bäst att klippa in lite mer av koden:

Ur matrix_test.cpp:

Kod: Markera allt

#include <iostream>
#include "matrix.h"

int main()
{

    ...

    Matrix m1(5, 5);
    // Fyll i data
    for (int i = 0; i < m1.getrows(); ++i)
      for (int j = 0; j < m1.getcols(); ++j)
        m1[i][j] = i*m1.getcols() + j;
    
    Matrix m2(5, 5);
    // Fyll i data
    for (int i = 0; i < m2.getrows(); ++i)
      for (int j = 0; j < m2.getcols(); ++j)
        m2[i][j] = 1;
    
    std::cout << "m1: \n" << m1 << "\n";
    std::cout << "m1.transpose(): \n" << m1.transpose() << "\n";
    std::cout << "m1 + m2: \n" << m1 + m2 << "\n";  // Kompileringsfel

    return 0;
}
matrix.h:

Kod: Markera allt

#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include "../lab14/vector.h"

class Matrix 
{
private:
  int m_, n_; // Rows (m) and columns (n) of matrix
  Vector **row;
protected:
  void check_bounds(int m, int n) const;
public:
  Matrix(int m, int n);
  Matrix(Matrix &ref);
  virtual ~Matrix();

  int getrows() const { return (m_); }
  int getcols() const { return (n_); }
  
  Matrix &operator=(const Matrix &);
  Vector &operator[](int m);
  const Vector operator[](int m) const;
  
/* Lab 1.3 - Matrix arithmetics */
  Matrix &identity();
  Matrix &transpose();

  Matrix operator+(const Matrix &) const;
  Matrix operator-(const Matrix &) const;
  Matrix operator*(const Matrix &) const;
  Matrix operator*(const int) const;
  
  Matrix operator-() const;    // Unary negation

};

std::ostream &operator<<(std::ostream &os, const Matrix &matrix);

#endif
och implementationen av operator+ (i matrix.cpp):

Kod: Markera allt

Matrix Matrix::operator+(const Matrix &ref) const
{
  if ((m_ != ref.m_) || (n_ != ref.n_))
    throw "Matrix::operator+(const Matrix &): Matrix dimensions must be equal.";

  Matrix temp(m_, n_);

  for (int i = 0; i < m_; ++i)
    for (int j = 0; j < n_; ++j)
      temp[i][j] = (*row[i])[j] + ref[i][j];
        
  return (temp);
}
Edit: det ska nämnas att de andra Matrix-operatorerna ger upphov till samma fel - ingen funkar, förutom = och [].

Arvid
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

Följande kompilerar utan fel för mig (Visual C++ toolkit 2003).

Kod: Markera allt

#include <iostream> 
#include "matrix.h" 

int main() 
{ 


    Matrix m1(5, 5); 

    Matrix m2(5, 5); 

    std::cout << "m1 + m2: \n" << m1 +m2 << "\n";  // Kompileringsfel 

    return 0; 
}

Kod: Markera allt

#ifndef MATRIX_H 
#define MATRIX_H 

#include <iostream> 
//#include "../lab14/vector.h" 

class Matrix 
{ 
	private: 
		int m_, n_; // Rows (m) and columns (n) of matrix 

	public: 
		Matrix(int m, int n); 


		Matrix operator+(const Matrix &) const; 


}; 

std::ostream &operator<<(std::ostream &os, const Matrix &matrix); 

#endif

Kod: Markera allt

#include "matrix.h"

Matrix::Matrix(int m, int n) {

}

Matrix Matrix::operator+(const Matrix &ref) const 
{ 
	Matrix temp(m_, n_); 

	return (temp); 
}

std::ostream &operator<<(std::ostream &os, const Matrix &matrix) {
	return os;
}
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Jo, det kompilerar fint för mig också, och även så om jag lägger till en tom copy-konstruktor Matrix(const Matrix &).

Vad sjutton är skillnaden?

:?: :humm:

Arvid
Användarvisningsbild
simon78
Inlägg: 1091
Blev medlem: 8 juni 2004, 11:05:51
Ort: Vinninga/Lidköping
Kontakt:

Inlägg av simon78 »

Nu har jag inte läst hela tråden men för att svara på OP.

Kod: Markera allt

 Matrix Matrix::operator+(const Matrix &ref) const
{
  if ((m_ != ref.m_) || (n_ != ref.n_))
    throw "Matrix::operator+(const Matrix &): Matrix dimensions must be equal.";

  Matrix temp(m_, n_); <--- Här vill den ha konstructorn

  for (int i = 0; i < m_; ++i)
    for (int j = 0; j < n_; ++j)
      temp[i][j] = (*row[i])[j] + ref[i][j];
       
  return (temp); <--- här copy-konstructorn
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

simon78: Deklarerar jag copy-konstructorn explicit så får jag kompileringsfel även där du visar, ja. (Observera att det finns en copy-konstruktor i klassen Matrix.)

Kolla på felet igen - kompilatorn vill ha en Matrix::Matrix(Matrix) (d.v.s. en som tar Matrix istf Matrix-referens som parameter).

Arvid
Användarvisningsbild
Abra Hana
Inlägg: 94
Blev medlem: 12 maj 2005, 13:20:58

Inlägg av Abra Hana »

*
Hur ser implimentation av dessa två klasser ?

public:
Matrix(int m, int n);
Matrix(Matrix &ref);

Dessa är inga standard konstruktorer , bör implimenteras .

*
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Implementationerna av metoderna ser ut så här:

Kod: Markera allt

Matrix::Matrix(int m, int n) : m_(m), n_(n)
{
  row = new Vector *[m_];
  for (int i = 0; i < m_; ++i)
    row[i] = new Vector(n_);
}

Matrix::Matrix(Matrix &ref) : m_(ref.m_), n_(ref.n_)
{
  row = new Vector *[m_];
  for (int i = 0; i < m_; ++i)
    row[i] = new Vector(n_); 
}
Copy-konstruktorn Matrix(Matrix &ref); är väl standard? Men eftersom jag har deklarerat den så implementerar jag den ju såklart också.

Arvid
Användarvisningsbild
Abra Hana
Inlägg: 94
Blev medlem: 12 maj 2005, 13:20:58

Inlägg av Abra Hana »

*

Jag ser inget samband mellan dessa :

// Här , du deklarerar och initierar en enkel objekt m1 av klassen Matrix .

Matrix m1(5,5)

// och här betraktar du denna objektet m1 som en array av klassen Matrix

m1[j] = i*m1.getcols() + j;

Du skapar en en enda Matrix objekt , men du försöker initiera inte mindre
än 25 matrix objekter när loopet har kört färdigt . Var kommer ifrån alla
andra 24 Matrix objekter ? .

Du gör samma sak för m2 !

*
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Inlägg av arvidb »

Matrix har ju operator[] deklarerad:

Kod: Markera allt

Vector &operator[](int m);
Vector i sin tur har också en operator[].

Dessutom är resultatet av uttrycket "i*m1.getcols() + j;" av typen int, och Matrix har ingen implicit konstruktor som tar en int som parameter - det går alltså inte att initiera en Matrix på det sättet.

Inget fel där alltså, så vitt jag kan se. En utskrift av m1 eller m2 visar också att det fungerar som avsett, nämligen att matrisens element tilldelas.

Arvid
Skriv svar