IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

error C3892 sous VS2008


Sujet :

C++

  1. #1
    Membre habitué Avatar de ke2007
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2007
    Messages : 82
    Points : 171
    Points
    171
    Par défaut error C3892 sous VS2008
    Bonjour,

    Je suis sous VS2008 et dans mon programme, j'obtiens l'erreur:
    Erreur 1 error C3892: 'this'*: vous ne pouvez pas assigner une variable const c:\....\caserailstation.cpp 37 monop2
    En gros, il me dit que je peux pas modifier la valeur d'une constante (ici this) ce que je comprend...

    Mais ce que je comprend pas, c'est d'où vient le problème.
    J'ai 2 classes l'une héritant de l'autre.

    Classe 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    class CaseProperty :
    	public Case
    {
    protected:
    	int pricePurchasing; // prix d'achat
    	int priceMortGage; // prix d'hypothèque
    	std::string name;
    	Player *owner;
     
    public:
    	CaseProperty(std::string = "", int = 0, int = 0);
    	virtual ~CaseProperty(void);
     
    	virtual int getRent() const = 0;
     
    	int getPricePurchasing() const;
    	int getPriceMortGage() const;
    	std::string getName() const;
    	Player* getOwner();
     
    	void setOwner(Player* p);
     
    	bool isOwned() const;
     
    	bool operator ==(const CaseProperty&);
    };
    Classe 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class CaseRailStation :
    	public CaseProperty
    {
    public:
    	CaseRailStation(std::string = "", int = 0, int = 0);
    	~CaseRailStation(void);
     
    	std::string getType() const;
    	void onCase(Player& p) const;
    	int getRent() const;
    };
    Le problème survient dans la méthode onCase qui est une méthode virtual pure de la classe mère Case.
    Sa définition est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    void CaseRailStation::onCase(Player &p) const
    {
    	if(this->isOwned())
    		cout << "Vous devez payer à " << this->owner->getName() << endl;
    	else 
    	{
    		cout << "Voulez vous acheter la " << this->name << " au prix de " << this->pricePurchasing << " F? (y/n)" << endl;
    		string res;
    		do
    		{
    			cout << "votre reponse: ";
    			cin >> res;
    			cout << endl;
    		}
    		while(res != "y" && res != "n");
     
    		if(res == "y" && p.getCash() >= this->pricePurchasing)
    		{
    			p.retryCash(this->pricePurchasing);
    			this->owner = &p; // L'erreur est sur cette ligne !!!!!
    		}
    	}
    }
    Je ne vois pas pourquoi je n'aurais pas le droit de modifier la valeur de la propriété "owner". Elle est protégé et non privé dans la classe CaseProperty.

    Si quelqu'un pouvait m'aider et m'expliquer mon problème ce serait super
    Merci d'avance !!

  2. #2
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	void onCase(Player& p) const;
    En plaçant le const ce dette manière, tu dis que cette méthode ne modifiera pas l'état de l'instance courrante de ta classe.

    Or, c'est ce que tu fais dans cette même méthode en tentant de modifier l'état de ton instance en modifiant l'un de ses attributs.

  3. #3
    Membre habitué Avatar de ke2007
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2007
    Messages : 82
    Points : 171
    Points
    171
    Par défaut
    Ok merci.

    Mais comment je peux modifier mon attribut?

    J'ai tenté de mettre une méthode setOwner(Player& p) dans ma classe CaseProperty.
    Cette méthode doit être commune à toute les classes filles et n'a pas besoin d'être redéfinie.

    Mais quand je l'appel dans ma méthode de CaseRailStation, il me met l'erreur:
    Erreur 1 error C2662: 'CaseProperty::setOwner'*: impossible de convertir un pointeur 'this' de 'const CaseRailStation' en 'CaseProperty &' c:\...\caserailstation.cpp 37 monop2

  4. #4
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Tu refais exactement la même chose que ton problème original, tu ne fais que le déplacer

    Dans une méthode const, ton pointeur this est en réalité un constant. Tu ne peux donc pas le modifier directement. Pour pouvoir le modifier, tu dois passer par une méthode non constante.

    Pour résoudre ton problème, il suffit de rendre ta méthode onCase non constante, c'est à dire enlever le const qui se situe à la fin de la déclaration de ta classe. Si cette méthode modifie l'état de ta classe, elle n'est pas constante.

    Par contre, tu as un effet de bord: cette méthode ne pourra plus être utilisée sur les objets constants ! (ce qui est logique)

  5. #5
    Membre habitué Avatar de ke2007
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2007
    Messages : 82
    Points : 171
    Points
    171
    Par défaut
    Ok, mais ma méthode est méthode virtual pure, donc elle est déclaré comme ceci dans la classe mère Case:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual void onCase(Player& p) const = 0;
    Je suis obligé d'avoir un const non?

  6. #6
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Si ta classe dérive d'une certaine interface ou classe qui définis cette méthode comme const (ce qui n'était pas le cas dans le code que tu avais montré), alors oui, tu as tout intérêt à ce que cette méthode soit const. Tu as alors un problème dans le rôle de ta méthode qui est ambigüe. Modifie-t-elle ou ne modifie-t-elle pas l'état courant ? Il faut le savoir. Est-ce que ta classe est elle réellement du type de son parent ?
    Tu peux également surcharger ta méthode afin de ne pas avoir de problème d'abstraction, et avoir d'un côté ta méthode const qui pourra être appellée par les classes manipulant des objets du type parent, et avoir une méthode non const pour les classes manipulant directement l'objet et ayant besoin de la méthode non const. Cependant, tes 2 méthodes ne feront strictement pas la même chose, et c'est un problème de design réellement important.

  7. #7
    Membre habitué Avatar de ke2007
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2007
    Messages : 82
    Points : 171
    Points
    171
    Par défaut
    Ouai je pense que je vais revoir la conception à ce niveau...
    Mais ça m'embete que je puisse pas modifié l'attribut, même en appelant une autre méthode qui le fasse...

    En tt cas merci pour la réponse ça ma aidé à comprendre le bug

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Mais ça m'embete que je puisse pas modifié l'attribut, même en appelant une autre méthode qui le fasse...
    Et pourtant, c'est tout à fait logique. En déclarant ta méthode "const", tu t'engages à ne pas modifier l'objet lors de l'appel. Et le client (celui qui appelle ta méthode) se repose sur cet engagement. Si tu pouvais rompre ton engagement comme si de rien était, autant ne pas prendre d'engagement du tout, il ne servirait plus à rien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. error LNK2019 sous VS2008 / Windows7
    Par emilien76 dans le forum C++
    Réponses: 2
    Dernier message: 18/01/2013, 14h46
  2. Réponses: 2
    Dernier message: 17/11/2008, 14h01
  3. Compilation Error VS2005 sous VISTA
    Par jeanke59 dans le forum ASP.NET
    Réponses: 9
    Dernier message: 03/09/2008, 11h04
  4. error LNK2019 sous evc4
    Par denny59 dans le forum MFC
    Réponses: 5
    Dernier message: 31/07/2008, 10h45
  5. Unexpected error (2121) sous Access 97 ???
    Par showa dans le forum Access
    Réponses: 7
    Dernier message: 05/12/2005, 22h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo