La fonction membre const peut-elle renvoyer un pointeur non-const à un membre de données?

Le Code passe en premier:

class A
{
    public:
        ...
        int *foo() const
        {
            return _px;
        }
    private:
        int *_px;
}

La fonction membre foo renvoie un pointeur non const sur private member _px, ce qui, je pense, ouvre une porte à la modification du Membre _px, n'est-ce pas?

Est foo une fonction membre const? Dois-je ajouter un const devant le type de retour?

Mise à JOUR

Ce qu'une fonction const-member devrait garantir, c'est qu'elle ne peut pas changer de membre de données, n'est-ce pas?

Dans mon cas, la fonction foo n'ouvre pas la porte à la modification class A s data-member _px, mais une porte à modifier ce que _px pointant vers, donc ma question Est, cela viole-t-il ce qu'une fonction const devrait garantir?

30
demandé sur Alcott 2012-01-09 17:05:53

5 réponses

Une fonction membre const ne peut renvoyer qu'un pointeur const ou une référence à un membre.

Cependant, votre exemple ne renvoie pas un pointeur à un membre; il renvoie une copie d'un membre qui se trouve être un pointeur. Cela est autorisé dans une fonction membre const (même si le pointeur pointe vers un autre membre).

Cela ne serait pas autorisé (notez qu'il renvoie maintenant une référence):

int *& foo() const {return _px;}

Mais ceci (renvoyant une référence const):

int * const & foo() const {return _px;}
29
répondu Mike Seymour 2012-01-09 13:09:11

int *_px devient int *const _px dans une fonction membre const cela implique que le pointeur ne peut pas être reseated mais les données pointées sont toujours modifiables. En outre, votre fonction renvoie une copie du pointeur, ce qui n'a pas d'importance de toute façon.

5
répondu Alok Save 2012-01-09 13:09:15

Cela n'ouvre pas la porte à la modification de _px mais plutôt à ce que _px pointe. C'est à vous de décider si vous souhaitez autoriser ou non.

Par exemple, un iterator::operator-> renverrait un pointeur non-const et const_iterator::operator-> renverrait un pointeur const. Les deux méthodes peuvent être const eux-mêmes.

4
répondu visitor 2012-01-09 13:14:55

Oui, pour votre cas, il peut. Cependant, il est généralement conseillé de ne pas le faire, car cela permet de changer les objets constants:

void f(const A& a) 
{
  *(a.foo()) = 42; // damn!
}
1
répondu sbi 2012-01-09 13:09:42

Oui, par exemple, voir les pointeurs std::streambuf:

protected:
   char* pbase() const;
   char* pptr() const;
   char* epptr() const;

Http://en.cppreference.com/w/cpp/io/basic_streambuf/pptr

0
répondu John Duffy 2018-05-03 09:38:52