L'appel d'une const fonction plutôt que de sa non-const version
J'ai essayé d'envelopper quelque chose de semblable à Qt de données partagée des pointeurs pour mes fins, et après essai, j'ai trouvé que, lorsque la const fonction doit être appelée, à sa non-const version a été choisi à la place.
Je compile avec C++0x options, et voici un code minimal:
struct Data {
int x() const {
return 1;
}
};
template <class T>
struct container
{
container() {
ptr = new T();
}
T & operator*() {
puts("non const data ptr");
return *ptr;
}
T * operator->() {
puts("non const data ptr");
return ptr;
}
const T & operator*() const {
puts("const data ptr");
return *ptr;
}
const T * operator->() const {
puts("const data ptr");
return ptr;
}
T* ptr;
};
typedef container<Data> testType;
void testing() {
testType test;
test->x();
}
Comme vous pouvez le voir, les Données.x est un const fonction, de sorte que l'opérateur -> appelés doivent être const un. Et quand je commenter la non-const, il compile sans erreurs, donc c'est possible. Et pourtant, mon terminal imprime:
"non const données ptr"
Est-ce un bug de GCC (j'ai 4.5.2), ou est-il quelque chose que je suis absent?
Vous devez vous connecter pour publier un commentaire.
Si vous avez deux surcharges qui diffèrent uniquement par leur
const
-ness, alors le compilateur résout l'appel en fonction de si*this
estconst
ou pas. Dans votre exemple de code,test
n'est pasconst
, de sorte que le non-const
surcharge est appelé.Si vous n'avez ceci:
vous devriez voir que l'autre surcharge est appelée, parce que
test2
estconst
.const
surcharge est considérée comme un meilleur match.test
est un non-const objet, de sorte que le compilateur trouve le meilleur match: Le non-const version. Vous pouvez appliquer constness avecstatic_cast
si:static_cast<const testType&>(test)->x();
EDIT: en passant, comme vous soupçonne de 99,9% du temps, vous pensez que vous avez trouvé un bogue du compilateur que vous devriez revoir votre code, car il y a probablement un peu bizarre caprice et le compilateur est en effet à la suite de la série.
Il n'a pas d'importance si
Data::x
est une fonction constante ou non. L'opérateur est appelé appartient àcontainer<Data>
classe et pasData
classe, et son exemple n'est pas constante, donc les non-constante de l'opérateur est appelé. S'il y avait une constante de l'opérateur disponible ou de l'instance de la classe a été constante elle-même, alors constante de l'opérateur aurait été appelé.Mais
testType
n'est pas un const objet.Ainsi, il fera appel à la non const version de ses membres.
Si les méthodes ont exactement les mêmes paramètres qu'il a à faire un choix sur la version à l'appel (de sorte qu'il utilise ce paramètre (la face cachée)). Dans ce cas, ce n'est pas const ainsi, vous obtenez le non-const méthode.
Cela n'affecte pas l'appel à x() que vous pouvez appeler une méthode const sur un non const objet.