Pisze program o matrixach, vectorach, scalarach... =P
I program działa i kompilował się poprawnie dopóki nie zabrałem sie za mnożenie. Mnożenie to postanowiłem zrealizować tworząc wirtualną klase Math i bazując na niej przeładowywać operator mnożenia. Math.h wygląda tak:
//math.h
#ifndef MATH_H
#define MATH_H
#include "scalar.h"
#include "vector.h"
#include "matrix.h"
class Math {
public:
virtual Math& operator*(Math& rv) = 0;
virtual Math& multiply(Scalar& s) = 0;
virtual Math& multiply(Vector& v) = 0;
virtual Math& multiply(Matrix& m) = 0;
virtual ~Math() {}
};
#endif //MATH_H
Teraz chciałem aby klasy Scalar, Vector, Matrix dziedziczyły po Math. Ich deklaracje wyglądają tak:
//Scalar.h
#ifndef SCALAR_H
#define SCALAR_H
#include "math.h"
#include <iostream>
class Scalar : public Math {
int value;
public:
//constructor
Scalar(int sz = 0) : value(sz) {}
//destructor
~Scalar() {}
//set value of value
void setValue(int val);
//overloading operator= for int
Scalar& operator=(const int& i);
//overloading operator= for Scalar
Scalar& operator=(const Scalar& s);
//overloading operator+
Scalar& operator+(const Scalar& s) const;
//overloading opeartor-
Scalar& operator-(const Scalar& s) const;
//overloading operator<<
friend std::ostream& operator<<(std::ostream& os, const Scalar& s);
//overloading in operator>>
friend std::istream& operator>>(std::istream& is, Scalar& s);
};
#endif //SCALAR_H
// Vector.h
#ifndef VECTOR_H
#define VECTOR_H
#include "math.h"
#include <iostream>
class Vector : public Math{
int size;
Scalar *scalars;
public:
//default constructor
Vector() : size(0), scalars(0) {}
//constructor
Vector(int sz);
//copy-constructor
Vector(const Vector& v);
//destructor
~Vector();
//return the size of Vector
int getSize() const;
//set vector size
void setSize(int sz);
//overloading bracket operator[]
Scalar& operator[](int x) const;
//overloading operator=
Vector& operator=(const Vector& v);
//overloading operator+
Vector& operator+(const Vector& v) const;
//overloading opeartor-
Vector& operator-(const Vector& v) const;
//overloading operator<<
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
//overloading in operator>>
friend std::istream& operator>>(std::istream& is, Vector& v);
};
#endif //VECTOR_H
// Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include "math.h"
#include <iostream>
class Matrix : public Math {
int size;
Vector *vectors;
public:
//default constructor
Matrix() : size(0), vectors(0) {}
//constructor
Matrix(int sz);
//copy-constructor
Matrix(const Matrix& m);
//destructor
~Matrix();
//return the size of Matrix
int getSize() const;
//overloading operator[]
Vector& operator[](int x) const;
//overloading operator=
Matrix& operator=(const Matrix& m);
//overloading operator+
Matrix& operator+(const Matrix& m) const;
//overloading operator-
Matrix& operator-(const Matrix& m) const;
//overloading operator<<
friend std::ostream& operator<<(std::ostream& os, const Matrix& m);
//overloading in operator>>
friend std::istream& operator>>(std::istream& is, Matrix& m);
};
#endif //MATRIX_H
A teraz co wypluwa g++
g++ -Wall -pedantic -O0 -g -c scalar.cpp
In file included from math.h:6,
from scalar.h:5,
from scalar.cpp:1:
vector.h:8: error: expected class-name before '{' token
vector.h:10: error: ISO C++ forbids declaration of 'Scalar' with no type
vector.h:10: error: expected ';' before '*' token
vector.h:25: error: ISO C++ forbids declaration of 'Scalar' with no type
vector.h:25: error: expected ';' before '&' token
vector.h: In constructor 'Vector::Vector()':
vector.h:13: error: class 'Vector' does not have any field named 'scalars'
In file included from math.h:7,
from scalar.h:5,
from scalar.cpp:1:
matrix.h: At global scope:
matrix.h:8: error: expected class-name before '{' token
In file included from scalar.h:5,
from scalar.cpp:1:
math.h:12: error: 'multiply' declared as a 'virtual' field
math.h:12: error: expected ';' before '(' token
scalar.cpp: In member function 'virtual Math& Scalar::operator*(Math&)':
scalar.cpp:33: error: no matching function for call to 'Math::multiply(Scalar&)'
math.h:13: note: candidates are: virtual Math& Math::multiply(Vector&)
math.h:14: note: virtual Math& Math::multiply(Matrix&)
scalar.cpp: At global scope:
scalar.cpp:42: error: no 'Math& Scalar::mulitply(Vector&)' member function declared in class 'Scalar'
matrix.h: In member function 'virtual Math& Scalar::multiply(Matrix&)':
matrix.h:9: error: 'int Matrix::size' is private
scalar.cpp:51: error: within this context
matrix.h:9: error: 'int Matrix::size' is private
scalar.cpp:52: error: within this context
matrix.h:9: error: 'int Matrix::size' is private
scalar.cpp:53: error: within this context
matrix.h:10: error: 'Vector* Matrix::vectors' is private
scalar.cpp:54: error: within this context
matrix.h:10: error: 'Vector* Matrix::vectors' is private
scalar.cpp:54: error: within this context
scalar.cpp:54: error: no match for 'operator*' in '*(m->Matrix::vectors + ((long unsigned int)(((long unsigned int)i) * 4ul))) * ((Scalar*)this)->Scalar::value'
scalar.cpp:55: error: invalid initialization of reference of type 'Math&' from expression of type 'Matrix'
make: *** [scalar.o] Error 1
Z takiego tłumu linijek wnioskuję, że cos sie nie zgadza z linkowaniem (chyba w ogóle nie widzi klasy Math), ale so far nie wpadłem na to co to może być.
Jak ktoś ma pomysł... bedę bardzo wdzięczny :D
W załączniku zamieszczam cały kod źródłowy razem z Makefilem