Salve, provando a compilare il seguente codice (gcc version 6.3.0 20170516):
// dado.h
#ifndef DADO_H
#define DADO_H
//La classe Dado fa parte dello spazio di nomi definito da Games
namespace Games {
class Dado;
}
class Games::Dado {
public:
Dado(); //COSTRUTTORE
Dado(int numFacce); //COSTRUTTORE OVERLOADED
Dado(const Dado& esistente); //COSTRUTTORE DI COPIA
Dado(Dado&& rvalue); //COSTRUTTORE DI SPOSTAMENTO
Dado& operator=(const Dado& esistente); //OVERLOADING OPERATORE DI COPIA DI UN OGGETTO
Dado& operator=(Dado&& rvalue); //OVERLOADING OPERATORE DI COPIA DI UN RVALUE
~Dado(); //DISTRUTTORE
int getFacciaCorrente() const; //METODO const. Inibisce la modifica di qualsiasi membro di classe
static int getRandom(int max); //METODO statico
void lanciaDado();
int getNumeroFacce() const;
void setNumeroFacce(int numFacce);
friend std::ostream& operator<<(std::ostream& out, const Dado& o);
private:
int* p_facciaCorrente;
int numeroFacce;
};
#endif // DADO_H
// dado.cpp
#include <iostream>
#include "dado.h"
#include <cstdlib>
#include <utility> //PER std::move
//DISTRUTTORE
Games::Dado::~Dado()
{
delete p_facciaCorrente;
}
//COSTRUTTORE
Games::Dado::Dado()
{
numeroFacce = 6;
p_facciaCorrente = new int;
*p_facciaCorrente = 0;
}
//COSTRUTTORE OVERLOADED
Games::Dado::Dado(int numFacce)
{
numeroFacce = numFacce;
p_facciaCorrente = new int;
*p_facciaCorrente = 0;
}
//COSTRUTTORE DI COPIA
Games::Dado::Dado(const Dado& esistente)
{
numeroFacce = esistente.numeroFacce;
p_facciaCorrente = new int;
*p_facciaCorrente = *(esistente.p_facciaCorrente);
}
//OVERLOADING OPERATORE DI UGUALE
Games::Dado& Games::Dado::operator=(const Dado& esistente)
{
numeroFacce = esistente.numeroFacce;
p_facciaCorrente = new int;
*p_facciaCorrente = *(esistente.p_facciaCorrente);
return *this;
}
//COSTRUTTORE DI SPOSTAMENTO
Games::Dado::Dado(Dado&& rvalue) : numeroFacce(rvalue.numeroFacce)
{
p_facciaCorrente = (std::move(rvalue.p_facciaCorrente)); //AGGIORNO IL PUNTATORE DEL NUOVO OGGETTO
rvalue.p_facciaCorrente = nullptr; //E CANCELLO QUELLO DEL VECCHIO
rvalue.numeroFacce = 0;
}
//OVERLOADING OPERATORE DI COPIA DI UN RVALUE
Games::Dado& Games::Dado::operator=(Dado&& rvalue)
{
numeroFacce = rvalue.numeroFacce;
p_facciaCorrente = (std::move(rvalue.p_facciaCorrente)); //AGGIORNO IL PUNTATORE DEL NUOVO OGGETTO
rvalue.p_facciaCorrente = nullptr; //E CANCELLO QUELLO DEL VECCHIO
rvalue.numeroFacce = 0;
}
int Games::Dado::getFacciaCorrente() const //METODO const. Inibisce la modifica di qualsiasi membro di classe
{
return *p_facciaCorrente;
}
int Games::Dado::getRandom(int max) //METODO definito statico nello header file
{
return (rand() % max + 1);
}
void Games::Dado::lanciaDado()
{
*p_facciaCorrente = getRandom(getNumeroFacce());
}
int Games::Dado::getNumeroFacce() const
{
return numeroFacce;
}
void Games::Dado::setNumeroFacce(int numFacce)
{
numeroFacce = numFacce;
}
std::ostream& operator<<(std::ostream& out, const Games::Dado& p)
{
return out << "la faccia corrente e: " << p.getFacciaCorrente();
}
//main.cpp
#include <iostream>
#include "dado.h"
using Games::Dado;
using namespace std;
int main ()
{
Dado d(10);
d.lanciaDado();
//UTILIZZO LA FUNZIONE FRIEND CHE FA LO OVERLOAD DELLO OPERATORE <<
std::cout << d << endl;
return 0;
}
ottengo questo errore:
/tmp/ccWSVmS6.o: nella funzione "main":
main.cpp:(.text+0x34): riferimento non definito a "Games::operator<<(std::ostream&, Games::Dado const&)"
collect2: error: ld returned 1 exit status
Se invece tolgo la classe Dado da dentro il namespace chiamato Games riesco a compilarlo perfettamente.
Qualcuno sa dirmi cosa non va nell'utilizzo del namespace?
grazie