2013-03-16 6 views
1

J'ai une classe de base (VectorRaw) et une classe dérivée (Vector).Pourquoi la classe dérivée ne peut pas accéder aux membres de la classe de base protégée?

J'utilise opérateur nouveau dans le constructeur de la classe de base pour créer une mémoire tampon, puis placement nouveau dans le constructeur de la classe dérivée pour y placer des éléments.

La classe de base a son destructor virtuel qui nettoie si quelque chose dans le constructeur de la classe dérivée va mal. Quand j'essaye de le compiler, il y a une erreur: tous les membres de la classe de base (begin, end, end_of_reserved) sont hors de portée dans toutes les fonctions des classes dérivées.

Qu'est-ce que je fais mal?

Voici mon code:

template <typename T> 
class VectorRaw { 
protected: 
    T * begin; 
    T * end; 
    T * end_of_reserved; 

    VectorRaw(const size_t size) { 
     begin = (T*) operator new (2 * size * sizeof(T)); 
     end = begin; 
     end_of_reserved = begin + 2 * size; 
    } 
    virtual ~VectorRaw<T>() throw() { 
     for (T * iter = begin; iter != end; ++iter) { 
      iter->~T(); 
     } 
     operator delete (begin); 
     end_of_reserved = end = begin; 
    } 
}; 

template <typename T> 
class Vector : public VectorRaw<T> { 
public: 
    Vector(const size_t size, const T& value) : VectorRaw<T>(size) { 
     for (end = begin; end != begin + size; ++end) 
      { 
      new (end) T (value); 
     } 
    } 
    bool Empty() const throw() { 
     return (begin == end); 
    } 
}; 
+0

Oops, édité :) – FrauHahnhen

Répondre

5

Étant donné que votre classe de base est une classe de modèle, vous devez accéder aux membres via le pointeur this:

template <typename T> 
class Vector : public VectorRaw<T> { 
public: 
    Vector(const size_t size, const T& value) : VectorRaw<T>(size) { 
     for (this->end = begin; this->end != this->begin + size; ++this->end) 
      { 
      new (this->end) T (value); 
     } 
    } 
    bool Empty() const { 
     return (this->begin == this->end); 
    } 

}; 

Il est nécessaire de reporter la recherche de ces noms jusqu'à ce que le paramètre de modèle soit connu. Il les rend noms dépendants. Voir this answer pour plus de détails.

+0

intéressant! J'ai essayé cela, mais mon compilateur se plaint de l'opérateur new (size_t) et propose d'utiliser l'opérateur new (size_t, void *) qui n'alloue pas de stockage – FrauHahnhen

+1

Vous utilisez les opérateurs non-placement faux. Changement 'begin = (T *) opérateur new (2 * Taille * sizeof (T))' à 'commencer = new T [2 * size];' et 'opérateur delete (commencer)' à 'supprimer [] commencer ; ' –

+0

@RemyLebeau, pourriez-vous s'il vous plaît expliquer la différence? Dans la documentation je vois pour operator new []: "La définition par défaut alloue de la mémoire en appelant l'opérateur new: :: operator new (size)" – FrauHahnhen

Questions connexes