2011-11-03 1 views
2

j'ai un certain nombre de classes qui dérivent d'une base virtal pur:Création d'un const share_ptr <pure_virtual_class> membre

class base { 
public: 
    virtual int f() = 0; 
}; 

class derived_0 : public base { 
public: 
    int f() {return 0;} 
}; 

class derived_1 : public base { 
public: 
    int f() {return 1;} 
}; 

Je ne mis deux classes dérivées par souci de concision, mais dans la pratique j'ai plus.

Et je voudrais créer une classe qui a un pointeur de const partagé à la base. Je voudrais faire à ce qui suit, mais je ne peux pas que je dois initialiser le pointeur const dans la liste d'initialisation:

class C{ 
public: 
    C(bool type) { 
     if(type) { 
      derived_0* xx = new derived_0; 
      x = shared_ptr<base>(xx); 
     } 
     else { 
      derived_1* xx = new derived1; 
      x = shared_ptr<base>(xx); 
     } 
    } 
private: 
    const share_ptr<base> x; 
}; 

Comment puis-je obtenir cette fonctionnalité?

+1

Vous avez oublié de marquer 'base :: f()' comme 'virtual' – Praetorian

+0

Merci Praetorian. Je l'ai réparé. – user1027953

+0

Je me demande ce que sont exactement les messages d'erreur. –

Répondre

6

Vous encapsulez la création de l'objet dans une fonction, comme ceci:

shared_ptr<base> create_base(bool type) { 
    if(type) { 
     return make_shared<derived_0>(); 
    } 
    else { 
     return make_shared<derived_1>(); 
    } 
} 

Et vous pouvez l'utiliser dans votre initialisation liste:

class C{ 
public: 
    C(bool type) 
    : x(create_base(type)) 
    {} 
private: 
    const share_ptr<base> x; 
}; 
3

Dans les cas simples comme celui-ci précise exemple:

class C 
{ 
    shared_ptr<Base> const x; 
public: 
    C(bool type) 
     : x(type 
      ? static_cast<Base*>(new Derived_0) 
      : static_cast<Base*>(new Derived_1)) 
    { 
    } 
}; 

(et oui, le static_cast, ou au moins un d'entre eux, sont nécessaire)

Dans plus de cas généraux, où la logique de décision est plus complexe, vous voudrez peut-être créer une fonction statique qui renvoie le shared_ptr, par exemple:.

class C 
{ 
    shared_ptr<Base> const x; 
    static shared_ptr<Base> makeSharedPtr(bool type); 
public: 
    C(bool type) 
     : x(makeSharedPtr(type)) 
    { 
    } 
}; 

Cela permettra une logique imaginable (et un ensemble plus complexe de paramètres ).

+0

Cela semble bon. – user1027953

+0

Notez que dans votre premier cas avec l'opérateur ternaire, utiliser 'static_cast' comme ça signifie que le destructeur doit être virtuel. Si vous créez à la place un 'shared_ptr' temporaire, le pointeur lui-même peut sauvegarder la classe dérivée exacte à supprimer plus tard. –

+0

@MarkB Mais en général, si une classe est polymorphe, vous voulez que le destructeur soit virtuel. –

Questions connexes