PDA

Visualizza la versione completa : [C++] Creazione di una classe "Point"


RooccoXXI
07-01-2011, 01:20
Volevo chiedere agli esperti...cosa ne pensate della mia classe Point? Manca qualcosa? C'è qualcosa da modificare?

Comunque ho un problemino. Vorrei fornire assieme alla classe alcune funzioni di utilità non appartenenti ad essa. Ma così come le ho messe mi danno errore! (non-member function 'double getDistance(const Point&)' cannot have cv-qualifier). Che errore è? Che errore faccio io?
Le funzioni servono a calcolare la distanza tra due oggetti qualsiasi della classe e quindi ovviamente non possono fare parte della classe stessa! (Lo so che è una complicazione ma mi sembra più "elegante" calcolare la distanza tra due punti piuttosto che la distanza tra un punto e un'altro, anche se alla fine il risultato è lo stesso).
Non avete capito niente?xD
Rispiego: preferisco fare come sto tentando di fare piuttosto che creare una funzione del tipo

double getDistance(const Point &P2) const
{
return sqrt(pow(x - P2.x, 2) + pow(y - P2.y, 2));
}

Lo trovo più "elegante". Sto facendo una cazzata?!xD.


#ifndef POINT_H
#define POINT_H

#include <iostream>
using std::ostream;
using std::istream;

class Point
{
friend ostream &operator<<(ostream &, const Point &);
friend istream &operator>>(istream &, Point &);

public:
Point();
Point(const double &, const double &);
~Point();

void setX(const double &);
void setY(const double &);
double getX() const;
double getY() const;

private:
double x;
double y;
};

double getDistance(const Point &) const;
double getDistance(const Point &, const Point &) const;

#endif


#include "point.h"

#include <iostream>
using std::endl;
using std::ostream;
using std::istream;

#include <cmath>
using std::pow;
using std::sqrt;

ostream &operator<<(ostream &output, const Point &point)
{
output << point.x << ' ' << point.y;

return output;
}

istream &operator>>(istream &input, Point &point)
{
input >> point.x;
input.ignore();
input >> point.y;

return input;
}

Point::Point()
{
setX(0);
setY(0);
}

Point::Point(const double &X, const double &Y)
{
setX(X);
setY(Y);
}

Point::~Point()
{
;
}

void Point::setX(const double &X)
{
x = X;
}

void Point::setY(const double &Y)
{
y = Y;
}

double Point::getX() const
{
return x;
}

double Point::getY() const
{
return y;
}

double getDistance(const Point &P1) const
{
return sqrt(pow(P1.getX(), 2) + pow(P1.getY(), 2));
}

double getDistance(const Point &P1, const Point &P2) const
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}

Cell
07-01-2011, 02:01
Perché getDistance ha un const alla fine della sua firma se non fa parte di nessuna classe? :confused:

Ippo343
07-01-2011, 09:58
double getDistance(const Point &P1) const
{
return sqrt(pow(P1.getX(), 2) + pow(P1.getY(), 2));
}

double getDistance(const Point &P1, const Point &P2) const
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}


Queste due funzioni le puoi trasformare in una sola, facendo così:



static Point Point::Zero()
{
return Point(0,0);
}

double getDistance(const Point &P1, const Point &P2 = Point::Zero) const
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}


In questo modo se non specifichi il secondo punto va in default all'origine, e quindi ti da il risultato della prima.

In più, dovresti aggiungere virtual al distruttore: se non metti virtual succede panico e morte quando derivi la classe.

RooccoXXI
07-01-2011, 10:32
Originariamente inviato da Cell
Perché getDistance ha un const alla fine della sua firma se non fa parte di nessuna classe? :confused:

Perché sono uno stupido!

RooccoXXI
07-01-2011, 10:38
Originariamente inviato da Ippo343


double getDistance(const Point &P1) const
{
return sqrt(pow(P1.getX(), 2) + pow(P1.getY(), 2));
}

double getDistance(const Point &P1, const Point &P2) const
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}


Queste due funzioni le puoi trasformare in una sola, facendo così:



static Point Point::Zero()
{
return Point(0,0);
}

double getDistance(const Point &P1, const Point &P2 = Point::Zero) const
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}


In questo modo se non specifichi il secondo punto va in default all'origine, e quindi ti da il risultato della prima.

In più, dovresti aggiungere virtual al distruttore: se non metti virtual succede panico e morte quando derivi la classe.

È meglio come hai proposto tu invece che fare un overloading delle funzioni? Come mai?

Comunque le classi virtuali non le ho ancora studiate...! Però da quello che mi ricordo se una classe contiene funzioni virtuali non può creare oggetti: serve solo a creare delle classi derivate. Giusto? Ma io ho bisogno di creare degli oggetti Point...!

RooccoXXI
07-01-2011, 13:35
Ho migliorato ulteriormente la classe Point.

Così è una classe ben fatta? Ci sono errori grossolani? Manca qualche funzione importante?! Si può ancora migliorare?
Grazie per i preziosi consigli! =).


#ifndef POINT_H
#define POINT_H

#include <iostream>
using std::ostream;
using std::istream;

class Point
{
friend ostream &operator<<(ostream &, const Point &);
friend istream &operator>>(istream &, Point &);

public:
Point operator+=(const Point &);
Point operator-=(const Point &);
bool operator==(const Point &) const;
bool operator!=(const Point &) const;

Point();
Point(const double &, const double &);
~Point();

void setX(const double &);
void setY(const double &);
void setXY(const double &, const double &);
double getX() const;
double getY() const;
void move(const double &, const double &);

private:
double x;
double y;
};

double getDistance(const Point &);
double getDistance(const Point &, const Point &);

#endif


#include "point.h"

#include <iostream>
using std::endl;
using std::ostream;
using std::istream;

#include <cmath>
using std::pow;
using std::sqrt;

ostream &operator<<(ostream &output, const Point &point)
{
output << point.x << ' ' << point.y;

return output;
}

istream &operator>>(istream &input, Point &point)
{
input >> point.x;
input.ignore();
input >> point.y;

return input;
}

Point Point::operator+=(const Point &P2)
{
return Point(x + P2.x, y + P2.y);
}

Point Point::operator-=(const Point &P2)
{
return Point(x - P2.x, y - P2.y);
}

bool Point::operator==(const Point &P2) const
{
if (x == P2.x and y == P2.y)
{
return true;
}

return false;
}

bool Point::operator!=(const Point &P2) const
{
if (x != P2.x or y != P2.y)
{
return true;
}

return false;
}

Point::Point()
{
setX(0);
setY(0);
}

Point::Point(const double &X, const double &Y)
{
setX(X);
setY(Y);
}

Point::~Point()
{
}

void Point::setX(const double &X)
{
x = X;
}

void Point::setY(const double &Y)
{
y = Y;
}

void Point::setXY(const double &X, const double &Y)
{
x = X;
y = Y;
}

double Point::getX() const
{
return x;
}

double Point::getY() const
{
return y;
}

void Point::move(const double &X, const double &Y)
{
setX(x + X);
setY(y + Y);
}

double getDistance(const Point &P1)
{
return sqrt(pow(P1.getX(), 2) + pow(P1.getY(), 2));
}

double getDistance(const Point &P1, const Point &P2)
{
return sqrt(pow(P1.getX() - P2.getX(), 2) + pow(P1.getY() - P2.getY(), 2));
}

shodan
07-01-2011, 13:43
Volendo puoi implementare i vari operatori matematici: +, - , * , / ;
operatori relazionali: <, <=, >, >=

RooccoXXI
07-01-2011, 13:55
Originariamente inviato da shodan
Volendo puoi implementare i vari operatori matematici: +, - , * , / ;
operatori relazionali: <, <=, >, >=

Giusto! +, -, * e / li implemento subito!xD.

Quanto a quelli relazionali... Che significa "un punto è maggiore di un altro"? Devo tener conto delle cordinate x, delle coordinate y, di tutte e due o matematicamente non hanno senso?!

shodan
07-01-2011, 14:07
E' passato parecchio tempo da quando ho finito le scuole, quindi non so se in effetti abbia senso. Però potresti aver bisogno di sapere se il punto X,Y, si trovi internamente al punto A,B e questo si verifica quando:
X < A && Y < B.
(In realtà sarà: X < A || !(A <X) && Y < B per via dello strict weak ordering).
Nota che non è un operatore campato in aria. Se in futuro userai una std::map per avere una mappa di punti, questo operatore è richiesto.
vedi: http://forum.html.it/forum/showthread.php?threadid=1440225 per i dettagli.

RooccoXXI
07-01-2011, 14:20
Originariamente inviato da shodan
E' passato parecchio tempo da quando ho finito le scuole, quindi non so se in effetti abbia senso. Però potresti aver bisogno di sapere se il punto X,Y, si trovi internamente al punto A,B e questo si verifica quando:
X < A && Y < B.
(In realtà sarà: X < A || !(A <X) && Y < B per via dello strict weak ordering).
Nota che non è un operatore campato in aria. Se in futuro userai una std::map per avere una mappa di punti, questo operatore è richiesto.
vedi: http://forum.html.it/forum/showthread.php?threadid=1440225 per i dettagli.

Si, ha senso solo cercare se un punto è interno. Lo terrò presente ma per ora lo lascio via perché a me non serve.

Ho implementato i miei operatori nel seguente modo, ma sembra funzionare solo l'operatore +. E inoltre a questo punto mi sembrano inutili gli operatori += e -=, sbaglio?


ostream &operator<<(ostream &output, const Point &point)
{
output << point.x << ' ' << point.y;

return output;
}

istream &operator>>(istream &input, Point &point)
{
input >> point.x;
input.ignore();
input >> point.y;

return input;
}

const Point &Point::operator=(const Point &P1)
{
x = P1.x;
y = P1.y;

return *this;
}

const Point &Point::operator+(const Point &P1)
{
x += P1.x;
y += P1.y;

return *this;
}

const Point &Point::operator-(const Point &P1)
{
x -= P1.x;
y -= P1.y;

return *this;
}

const Point &Point::operator*(const Point &P1)
{
x *= P1.x;
y *= P1.y;

return *this;
}

const Point &Point::operator/(const Point &P1)
{
x /= P1.x;
y /= P1.y;

return *this;
}

Point Point::operator+=(const Point &P2)
{
return Point(x + P2.x, y + P2.y);
}

Point Point::operator-=(const Point &P2)
{
return Point(x - P2.x, y - P2.y);
}

bool Point::operator==(const Point &P2) const
{
if (x == P2.x and y == P2.y)
{
return true;
}

return false;
}

bool Point::operator!=(const Point &P2) const
{
if (x != P2.x or y != P2.y)
{
return true;
}

return false;
}

Loading