1 votes

Erreur de compilation avec la fonction const

Je ne sais pas si je rate quelque chose de fondamental. Mais je ne parviens pas à comprendre pourquoi le compilateur génère l'erreur pour ce code :

class A
{
};

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

B::B()
{
    m_p = new A;
}

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why? 
    return &m_a;
}

EDIT : L'erreur du compilateur est : error C2440 : 'return' : cannot convert from 'const class A *' to 'class A *' La conversion perd les qualificatifs.

13voto

Konrad Rudolph Points 231505

const dans la signature de la fonction indique au compilateur que les membres de l'objet ne peuvent pas être modifiés. Pourtant, vous retournez un objet non const pointeur à un membre, permettant ainsi une violation de cette promesse.

Dans votre classe B En effet, vous ne faites/rompez aucune promesse puisque vous ne retournez pas un pointeur vers un membre, mais une copie de celui-ci (et le membre se trouve être un pointeur).

3voto

therefromhere Points 21329

C'est parce que vous renvoyez un pointeur non-const vers un membre d'une fonction const.

La première partie fonctionne parce que vous retournez un fichier copie d'un pointeur membre, donc cela ne viole pas le caractère constant de la fonction get :

class B
{
public:
    B();
    A* get() const;

private:
    A* m_p;
};

A* B::get() const
{
    //This is compiling fine
    return m_p;
}

Mais le bit suivant génère l'erreur de compilation (sur gcc 4)

testfile.cpp:37 : erreur : conversion invalide de 'const A*' vers 'A*'.

Parce que votre fonction const get fournit un accès non-const à m_a en lui retournant un pointeur non-const.

class C
{
public:
    A* get() const;
private:
    A m_a;
};

A* C::get() const
{
   //Compiler generates an error for this. Why?
    return &m_a;
}

1voto

newgre Points 2821

Parce que le pointeur retourné n'est pas const. Changez-le en ceci :

class C
{
public:
    const A* get() const;
private:
    A m_a;
};

const A* C::get() const
{
    //Compiler generates an error for this. Why? 
    return &m_a;
}

Remarquez que C::get() renvoie maintenant un pointeur constant vers A.

0voto

Frederick The Fool Points 9092

Fonctions membres marquées const ne peut pas retourner une référence non-const ou un pointeur vers une variable privée. Si le compilateur l'autorisait, toute personne extérieure à votre classe serait en mesure de modifier ladite variable privée et la fonction const sur la fonction perdrait son sens.

0voto

strager Points 41713

Ce problème peut être illustré par un exemple plus simple :

class MyClass {
public:
    int *get() const;
private:
    int value;
};

int *MyClass::get() const {
    return &value;
}

En MyClass::get() const , value a le type const int . Lorsque vous le déréférencez, vous obtenez const int * . Ce type ne peut pas être casté en toute sécurité (implicitement) en int * . Pour corriger votre problème, faites get() retourner const int * .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X