1

I have a base class (VectorRaw) and a derived class (Vector).

I use operator new in the constructor of the base class to create a memory buffer and then placement new in the constructor of the derived class to place elements therein.

The base class has its virtual destructor which cleans up if something in the constructor of the derived class goes wrong.

When I try to compile it, there is an error: all of the base class' members (begin, end, end_of_reserved) are out of scope in all derived classes' functions.

What am I doing wrong?

Here's my 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);
    }
};
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
FrauHahnhen
  • 143
  • 2
  • 11

1 Answers1

5

Since your base class is a template class, you need to access the members through the this pointer:

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);
    }

};

This is necessary to defer the lookup of these names until the template parameter is known. It makes them dependent names. See this answer for more details.

Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • interesting! I actually tried this, but then my compiler complains about operator new(size_t) and proposes to use operator new(size_t, void*) which doesn't allocate any storage – FrauHahnhen Mar 16 '13 at 18:30
  • 1
    You are using the non-placement operators wrong. Change `begin = (T*) operator new (2 * size * sizeof(T));` to `begin = new T[2 * size];` and `operator delete (begin);` to `delete[] begin;` – Remy Lebeau Mar 16 '13 at 18:35
  • @RemyLebeau, could you please explain the difference? In documentation I see for operator new[]:"The default definition allocates memory by calling operator new: ::operator new (size)" – FrauHahnhen Mar 16 '13 at 18:51