2010-03-10 4 views
0

J'ai une question rapide sur l'encapsulation des types spécifiques avec typedef. Dire que j'ai une classe Foo dont le constructeur prend une certaine valeur, mais je veux cacher le type spécifique en utilisant typedef:Comment masquer complètement un type spécifique en utilisant typedef?

class Foo { 
public: 
    typedef boost::shared_ptr< std::vector<int> > value_type; 
    Foo(value_type val) : val_(val) {} 
private: 
    value_type val_; 
}; 

Mais dans ce cas, la fonction principale doit encore connaître le type (donc il utilise explicitement std::vector<int>):

int main() { 
    Foo::value_type val(new std::vector<int>()); 
    val->push_back(123); 
    Foo foo(val); 
    return 0; 
} 

Comment puis-je résoudre ce problème tout en évitant une copie en profondeur du vecteur dans le constructeur Foo?

Répondre

6

Diverses solutions:

Foo::value_type val(new Foo::value_type::element_type()); 
// least change from your current code, might be too verbose or too 
// coupled to boost's smart pointer library, depending on your needs 

Foo::value_type val(new Foo::element_type()); 
// add this typedef to Foo: typedef value_type::element_type element_type; 

Foo::value_type val = Foo::new_value_type(); 
// static method in Foo, allows you to even easily change from new (as you 
// encapsulate the whole smart pointer, and can specify another deleter to the 
// boost::shared_ptr) 

struct Foo { 
    static value_type new_value_type() { // function used above 
    return value_type(new value_type::element_type()); 
    } 
}; 

Cependant, si tout ce que vous voulez est d'avoir un membre de vecteur Foo initialisé à partir des données à l'extérieur sans le copier, au lieu de partager réellement à travers un shared_ptr, alors je ne voudrais pas utiliser un shared_ptr à tous. Prenez une référence dans le ctor de Foo et dans le document indiquant qu'il change l'objet.

struct Foo { 
    typedef std::vector<int> value_type; 
    explicit Foo(value_type& val) { 
    using std::swap; 
    swap(val, _val); 
    } 

private: 
    value_type _val; 
}; 

int main() { 
    Foo::value_type val; 
    val->push_back(123); 
    Foo foo(val); 
    return 0; 
} 
+0

Merci, en particulier l'opération 'swap()' est exactement ce dont j'ai besoin. – Frank

1

Il n'y a pas de copie en profondeur dans l'exemple fourni. Shared_ptr est copié, mais il n'y a qu'un seul vecteur créé. Vous pouvez le confirmer en appelant push_back une seconde fois après le constructeur Foo et en notant que Foo.val_ change également.

+0

C'est un malentendu. Je voulais dire que je veux corriger le problème de typedef, mais sans introduire de copie en profondeur. ('shared_ptr' a été utilisé pour éviter la copie en premier lieu.) J'ai changé le texte pour être plus clair à ce sujet. – Frank

Questions connexes