2015-08-18 1 views
1

Je trouve irritant que je puisse appeler des fonctions non const d'un objet si j'ai un pointeur sur cet objet. Je ne peux pas laisser le pointeur être un pointeur const car il y a aussi des fonctions non-const que j'ai besoin d'appeler. Par conséquent, ma seule option semble faire static_casts pour s'assurer que constness fonctionne également à travers les pointeurs. Voici un exemple minimal:Quel est le surdébit d'exécution de static_cast si vous ajoutez une constité tout en conservant le même type?

class MyClassImpl 
{ 
    MyClassImpl(void) : m_i(0) {} 

    int increment(void) { 
    ++m_i; 
    return m_i; 
    } 

    private: 
    int m_i; 
}; 

class MyClass 
{ 
    MyClass(void) : m_pImpl(new MyClassImpl()){} 

    ~MyClass(void) { 
    delete m_pImpl; 
    } 

    int doNothing(void) const { 
    m_pImpl->increment(); // works although MyClassImpl::increment() is non-const 
    // static_cast<const MyClassImpl *>(m_pImpl)->increment(); // this will not compile because of non-constness 
    } 


    private: 
    MyClass(const MyClass & rhs); 
    MyClassImpl * m_pImpl; 
}; 

Cependant, je me demande si le static_cast a un coût à l'exécution. Les static_casts sont-ils complètement évalués au moment de la compilation ou y a-t-il une surcharge, en supposant que doNothing() est souvent appelé?

Modifier: Ma question est différente de C++ static_cast runtime overhead parce que dans mon cas, le static_cast ajoute seulement const. Les autres utilisateurs ayant trouvé cette question pourraient être intéressés par la question mentionnée.

+0

La surcharge dépend des types. Si vous ajoutez uniquement const, il n'y a pas de surcharge. –

+0

Pourquoi un 'static_cast' au lieu d'un' const_cast'? – nwp

+0

@nwp: Une static_cast peut ajouter une constité sans la supprimer. Une const_cast peut supprimer constness. Par conséquent, static_cast est plus sûr. – Fabian

Répondre

2

La surcharge d'exécution est essentiellement une copie de pointeur, qui peut être entièrement optimisée.

Mais dans votre cas, j'envisager de changer int m_i;-mutable std::atomic<int> m_i; et faire increment constante dans la classe de base aussi. Il ressemble à un compteur de référence et mon chemin vous permet de (i) conserver const -correctness et (ii) être thread-safe. Je considérerais également le changement int à unsigned pour éviter le comportement indéfini si m_i devient trop grand.

+1

Pourquoi le pointeur serait-il copié? Dans ce cas, seules les modifications de qualification de 'const' sont donc probablement des no-op. – Quentin

+1

En effet, le compilateur peut optimiser un temporaire. Mais ce n'est pas ** pire ** qu'une copie de pointeur. – Bathsheba