Problème constructeur par copie

Résolu/Fermé
Hurobaki Messages postés 53 Date d'inscription dimanche 23 mars 2014 Statut Membre Dernière intervention 10 mars 2017 - 14 mai 2016 à 12:45
Hurobaki Messages postés 53 Date d'inscription dimanche 23 mars 2014 Statut Membre Dernière intervention 10 mars 2017 - 15 mai 2016 à 14:28
Bonjour à tous,

Comme dit dans le titre, je rencontre un problème dans la création d'un constructeur par copie en C++.

Voici mon main :

User *u = new User("User2", "User2", new Date(12, 10, 1994), new Address(12, 60300, "Rue Berlioz"), "Username2", "Password");


	User *t = new User("User1", "User1", new Date(14, 10, 1994), new Address(35, 60300, "Rue Decroze"), "Username1", "Password");

	std::cout << *t << std::endl;

	std::cout << *u << std::endl;

	*t = *u;

	std::cout << *t << std::endl;

	delete u;
	delete t;


Je créé deux nouvelles instances de la class User. Ensuite je souhaite mettre les informations de l'User u dans l'User t, mais lorsque je lance l'application une erreur apparaît et l'application cesse de fonctionner.

J'ai pensé que ce serait à cause des pointeurs mais je ne parviens pas à résoudre mon problème ... Je vous mets ma classe User pour que vous puissiez voir mon code :

class User : public Person
{
	private:
		std::string _username;
		std::string _password;
	public:
		User(const std::string u = "guest", const std::string p = "pass");
		User(const std::string f, const std::string l, const Date *d, const Address *a, std::string u, std::string p);
		User(const User& u);
		~User();


	friend std::ostream& operator<<(std::ostream& os, const User& p);
};

User::User(const std::string u,const std::string p)
	:Person(),_username(u),_password(p)
{
}

User::User(const std::string f, const std::string l, const Date *d, const Address *a, std::string u, std::string p)
	: Person(f,l,d,a), _username(u), _password(p)
{

}

User::User(const User & u)
{
	
	this->_password = u._password;
	this->_username = u._username;
	this-> setFirstname(u.getFirstname());
	this->setLastname(u.getLastname());
	this->setDateofbirth(Date(u.getDateofbirth()));
	this->setAddress(Address(u.getAddress()));
}

class Person
{

	private:
		std::string _firstname;
		std::string _lastname;
		Date *_dateofbirth;
		Address *_address;

	public:
		Person();
		Person(const std::string first, const std::string last, const Date *birth, const Address *address);

		Person(const Person& p);
		virtual ~Person();

		std::string getFirstname() const;
		std::string getLastname() const;
		Date getDateofbirth() const;
		Address getAddress() const;

		void setFirstname(const std::string f);
		void setLastname(const std::string l);
		void setDateofbirth(const Date& d);
		void setAddress(const Address& a);




		friend std::ostream& operator<<(std::ostream& os, const Person& p);
};

Person::Person()
	:_firstname("None"),_lastname("None"),_dateofbirth(new Date()),_address(new Address())
{
}

Person::Person(const std::string first, const std::string last, const Date *birth, const Address *address)
	: _firstname(first), _lastname(last), _dateofbirth(new Date(birth->getDay(),birth->getMonth(),birth->getYear())), _address(new Address(address->getNumber(),address->getPostal(),address->getStreet()))
{

}

Person::Person(const Person& p)
{
	this->_firstname = p._firstname;
	this->_lastname = p._lastname;
	this->_dateofbirth = new Date(p._dateofbirth->getDay(), p._dateofbirth->getMonth(), p._dateofbirth->getYear());
	this->_address = new Address(p._address->getNumber(), p._address->getPostal(), p._address->getStreet());
}


Person::~Person()
{
	std::cout << "Destructor Person in progress" << std::endl;
	delete _dateofbirth;
	delete _address;
}


Voilà j'espère avoir tout donner comme informations, si jamais vous avez une solution, ou même des conseils si mon code est mal écrit je suis ouvert à tout ! :D

Merci d'avance,

Cordialement.
A voir également:

2 réponses

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
15 mai 2016 à 03:35
Bonjour,

Ton code est un impressionnant mélange de choses à ne pas faire.
  • Tout d'abord, quand tu fait *t = *u, ce n'est pas le constructeur par copie qui est appelé mais l'opérateur de copie. Hors tu n'en as pas défini.
  • A chaque pointeur initialisé par un new, un delete doit être associé. ni plus ni moins. Il manque des delete et il y des new de trop dans ton code.
  • Les fonctions setDateofbirth() et setAdress() ne sont pas indiquées, elles sont des pièges avec ta structure.
  • User n'a pas à manipuler les données de Person, il doit se servir de Person (et dans les constructeurs, il passe directement les paramètres à Person). Par exemple, le constructeur par copie de User n'utilise pas le constructeur par copie de Person, c'est une erreur.
  • il y a ces erreurs dans tes fonctions, relis les bien.

Je te donne en exemple des fonctions manquantes.
User& User::operator=(const User& u) // operateur de copie de User
{   if ( &u != this ) {
        this.Person::operator=( u );     // copie de Person

	this->_password = u._password;
	this->_username = u._username;
    }
    return *this;
}
Person& Person::operator=( const Person& u ) // operateur de copie de Person
{   if ( &u != this ) {
        this->setFirstname( u.getFirstname() );
        this->setLastname( u.getLastname() );
        this->setDateofbirth( Date(u.getDateofbirth()) );
        this->setAddress( Address(u.getAddress()) );
    }
    return *this;
}
void Perso::setAddress( const Address& a ) {
    delete _adress; // detruire precedent si existe
    _adress = 0; // garantir un etat 'safe' avant un new
    _adress = new Adress( a->getNumber(), a->getPostal(), a->getStreet() ); 
}
//  Le constructeur corrigé de User qui utilise le constructeur de copie de Person
User::User( const User& u ) : Person( u ) , _password(u.password) , _username(u._username)
{
}
0
Hurobaki Messages postés 53 Date d'inscription dimanche 23 mars 2014 Statut Membre Dernière intervention 10 mars 2017
15 mai 2016 à 14:28
Bonjour Dalfab,

Je te remercie pour ta réponse et pour toutes tes explications, je viens de tout lire et cela va m'être extrêmement utile ! Je n'ai pas encore beaucoup d'expérience en C++ et cela m'aide beaucoup de voir ce que je fais mal !

Je vais reprendre mon code en rectifiant mes erreurs et surtout en comprenant bien comment tu as fais.

Merci beaucoup, bonne journée.
0