Hilfe bei Klassendefinition
-
Erstmal sortiere ich die Klasse ein wenig, nur damit ich durchblicke...

class matrix { char* s; double minimum,maximum; public: double min(); double max(); double quicksort(); matrix( int anzzeilen, int anzspalten) { ???=new double[anzzeilen][anzspalten]; return ???; } matrix( int anzzeilen ) { ???=new double[anzzeilen]; return ???;}; } };matrix A(4)
Das ist ziemlich einfach. Du sagst mit der Zeile ja, dass du ein Objekt vom Typ "Matrix" willst. Zusätzlich übergibst du der Matrix noch einen Start-Wert, hier die '4'.
Die Startwerte bekommst du, wie du's ja schon hast, im Konstruktor der Klasse. Wieso du da aber Zeiger auf einen Zahlenwert übergeben willst, ist mir schleierhaft. Wie dem auch sei, das "const int*" aus dem Konstruktor kannst du getrost durch "int" austauschen, schließlich willst du keinen Zeiger auf eine Zahl, die du nicht verändern darfst, sondern einfach nur eine Zahl
Für den Rest lege ich dir der Einfachheit halber (will mir keinen Wolf schreiben ;)) mal Google mit dem Stichwort "C++ Tutorial" ans Herz. Dir fehlen ganz einfach die Grundlagen, welche du (meiner Meinung nach) vor dem Klassen-Konzept lernen solltest. Du solltest zumindest wissen, was ein Zeiger ist, was Zeichenketten sind usw.
Lass dich aber nicht entmutigen, es kommt der Tag an dem dein erster selbstgeschriebener Source kompiliert!
-
template <typename T> class matrix { public: matrix(std::size_t row = 1, std::size_t col = 1) : m_row(row), m_col(col) { m_data = new T*[row]; for (std::size_t cur = 0; cur < row; ++cur) m_data[cur] = new T[col]; } ~matrix() { for (std::size_t cur = 0; cur < m_row; ++cur) delete [] m_data[cur]; delete [] m_data; } public: T const & at(std::size_t row, std::size_t col) const { if (row > m_row || col > m_col) throw std::out_of_range("col or row"); return m_data[row][col]; } T const & min() const { T const & min; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) min = std::min(m_data[row][col], min); return min; } T const & max() const { T const & max; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) max = std::max(m_data[row][col], max); return max; } private: T** m_data; std::size_t m_row; std::size_t m_col; };...
sind nen paar const usw. zu viel drin und kann sein das ich col und row vertauscht hab
an sonnsten ... so wird's gemacht 
-
Bleibt nur eine Frage: Warum nicht template<typename T,size_t rows,size_t cols>?

Ansonsten schöne Klasse und ich denke Theodor wird sie auf Anhieb verstehen
Und noch eine Frage meinerseits: Macht es eigentlich einen Unterschied ob man template<typename T> oder template<class T> verwendet?
-
template <typename T> oder template <class T> macht keinen Unterschied. Das konstrukt mit typename(im gegensatz zu class) suggeriert dem Benutzer, dass auch primitive datentypen benutzt werden können.
-
Badestrand schrieb:
Bleibt nur eine Frage: Warum nicht template<typename T,size_t rows,size_t cols>? ...
Kommt drauf an, was man will: Mit rows/cols als template-Parameter kann man direkt ein statisches Array verwenden ... aber die Größe eben auch nicht mehr zur Laufzeit ändern.
Außerdem haben unterschiedlich dimensionierte Matrizen dann auch unterschiedliche (= inkompatible) Typen ... kann gewollt sein, muss aber nicht.Gruß,
Simon2.
-
megaweber schrieb:
template <typename T> oder template <class T> macht keinen Unterschied. Das konstrukt mit typename(im gegensatz zu class) suggeriert dem Benutzer, dass auch primitive datentypen benutzt werden können.
ich sehs eigentlich genau andersrum: "class" suggeriert, dass auch klassen verwendet dürfen. im gegensatz zu typename, welches andeutet, dass die methode für primitive typen gedacht ist.
-
thordk schrieb:
ich sehs eigentlich genau andersrum: "class" suggeriert, dass auch klassen verwendet dürfen. im gegensatz zu typename, welches andeutet, dass die methode für primitive typen gedacht ist.
Dies ist aber eine unübliche Betrachtungsweise (zumal typename auch an anderen Stellen als im Templatekopf verwendet wird, und es dort auch Klassen als Möglichkeit gibt).
Um grade Anfänger nicht durcheinander zu bringen wäre es besser sich an die Definitionen anzulehnen, die man auch so in vielen Fachbüchern findet:
class : Nur Klassentypen
typename : Klassentypen + primitive Typencu André
-
Hmm ... ich wusste doch das zu viele const in der Klasse sind ... also bei at müssen 2 raus
Sonnst kannst du die werte nie ändern 
namespace math { template <typename T> class matrix { public: matrix(std::size_t row = 1, std::size_t col = 1) : m_row(row), m_col(col) { m_data = new T*[row]; for (std::size_t cur = 0; cur < row; ++cur) m_data[cur] = new T[col]; } ~matrix() { for (std::size_t cur = 0; cur < m_row; ++cur) delete [] m_data[cur]; delete [] m_data; } public: T& at(std::size_t row, std::size_t col) { if (row > m_row || col > m_col) throw std::out_of_range("col or row"); return m_data[row][col]; } T const & min() const { T const & min; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) min = std::min(m_data[row][col], min); return min; } T const & max() const { T const & max; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) max = std::max(m_data[row][col], max); return max; } std::size_t size() const { return (m_row * m_col); } private: T** m_data; std::size_t m_row; std::size_t m_col; }; }; int main() { math::matrix<double> mat(4, 4); mat.at(1, 1) = mat.size(); }
so bin ich zufrieden ... hatte auch an ne clear-Methode gedacht ... aber ich kann ja nicht davon ausgehen das ich einer normalen Klasse 0 zuweisen kann
Könnte aber auch hingehen und alles einmal löschen und dann neu anlegen ... also man kann nochn paar sachen implementieren ...Aja zur Suche: Wie willst de es denn sortiert haben? Soll jede Zeile für sich sortiert sein oder alles zusammen?(was nicht geht ...)
-
So ... jetzt können wir auch noch resizen ... und zu beachten: operator () wirft natürlich keine exception ... at aber schon ... so wie std::vector udg. auch.
#include <algorithm> namespace math { template <typename T> class matrix { public: matrix(std::size_t row = 1, std::size_t col = 1) : m_row(row), m_col(col) { m_data = new T*[row]; for (std::size_t cur = 0; cur < row; ++cur) m_data[cur] = new T[col]; } ~matrix() { for (std::size_t cur = 0; cur < m_row; ++cur) delete [] m_data[cur]; delete [] m_data; } T& operator ()(std::size_t row, std::size_t col) { return m_data[row][col]; } public: T& at(std::size_t row, std::size_t col) { if (row > m_row || col > m_col) throw std::out_of_range("col or row"); return m_data[row][col]; } T const & min() const { T const & min; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) min = std::min(m_data[row][col], min); return min; } T const & max() const { T const & max; for (std::size_t row = 0; row < m_row; ++row) for (std::size_t col = 0; col < m_col; ++col) max = std::max(m_data[row][col], max); return max; } std::size_t size() const { return (m_row * m_col); } void resize(std::size_t row, std::size_t col) { T** tmp_data = new T*[row]; for (std::size_t cur_row = 0; cur_row < row; ++cur_row) { tmp_data[cur_row] = new T[col]; for (std::size_t cur_col = 0; cur_col < col; ++cur_col) if (cur_col < m_col && m_row > cur_row) tmp_data[cur_row][cur_col] = m_data[cur_row][cur_col]; } for (std::size_t cur = 0; cur < m_row; ++cur) delete [] m_data[cur]; delete [] m_data; m_data = tmp_data; m_row = row; m_col = col; } private: T** m_data; std::size_t m_row; std::size_t m_col; }; }; double test() { math::matrix<double> mat(4, 4); mat.at(1, 1) = mat.size(); mat.resize(6,6); mat(5, 1) = 1; return mat.at(5, 1); }...
-
aja ... wer auf die Standardbibliothek verzichten will ... muss nur kurz
namespace math { template <typename T> T& min(T const& a, T const& b) { return (a > b ? b : a); } template <typename T> T& max(T const& a, T const& b) { return (a > b ? a : b); } };am Anfang schreiben und aus std::max bzw std::min einfach math::min bzw math::max machen

-
Hier noch was

namespace math { template <typename T> void bubble_sort(T*& arr, std::size_t size) { bool redo = false; do { redo = false; for (std::size_t i = 0; (i < (size - 1) && arr[i] != NULL && arr[i+1] != NULL); ++i) if (arr[i] > arr[i + 1]) { std::swap<T>(arr[i], arr[i + 1]); redo = true; } } while (redo == true); } };=>
class matrix { // ... void sort() { for (std::size_t cur_row = 0; cur_row < m_row; ++cur_row) bubble_sort<T>(m_data[cur_row], m_col); } // ... };
-
(D)Evil schrieb:
So ... jetzt können wir auch noch resizen ... und zu beachten: operator () wirft natürlich keine exception ... at aber schon ... so wie std::vector udg. auch.
Jetzt hast du dich ja richtig ausgetobt. Ich finde die Klasse gut, aber wieso wirft der operator() keine exception? Das macht aus meiner Sicht keinen Sinn.
-
hmm ... nja wollte eigentlich nen [][] operator implementieren ... aber das ist ja nicht so ohne weiteres möglich ... deswegen hab ich dne operator () genommen ...[] wirft auch keine exceptions in der std. lib
nja ist eigentlich nicht sooo sinvoll
aber egal ... mir ist gerade auch eingefallen das der operator [][] garnicht sooo das problem wäre ... aber egal ^^