How to be sure my array only takes pointer

V

Vincent RICHOMME

Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?


template<typename T> class ArrayPtr : public std::vector<T>
{
public:

inline void Add(T object)
{
push_back(object);
}

inline void Clear()
{
clear();
}

int GetCount()
{
return size();
}
};


The goal is to empty my vector and to deallocate pointer when I call
Clear().
 
F

Frederick Gotham

Vincent RICHOMME posted:
Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?


Perhaps some compile-time assertions along the following lines:

(This won't compile with g++, not sure why.)

#include <vector>

#define ENSURE_LEGALITY_OF_EXPRESSION(expr) \
int (*VerifyFuncDecl())[(unsigned)!!sizeof(expr)]

template<int i>
struct VerifyType {
unsigned bitfield_cant_be_negative : i;
};

#define COMPILE_TIME_ASSERT(expr) \
int (*VerifyFuncDecl())[(unsigned)!!sizeof(VerifyType<(expr)?1:-1>)]

template<class T>
class PtrArray : public std::vector<T>
{
private:

ENSURE_LEGALITY_OF_EXPRESSION( *T() );

COMPILE_TIME_ASSERT( sizeof(T) <= sizeof(void*) );

using std::vector<T>::push_back;
using std::vector<T>::clear;
using std::vector<T>::size;

public:

inline void Add(T const ptr)
{
push_back(ptr);
}

inline void Clear()
{
clear();
}

int GetCount()
{
return size();
}
};

int main()
{
PtrArray<char*> arr;
}
 
I

Ian Collins

Vincent said:
Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?
If you don't want to expose all the methods of vector, how about

template<typename T> class ArrayPtr : std::vector<T*>
{
public:

void Add(T* object)
{
push_back(object);
}

template<typename T> class ArrayPtr : public std::vector<T>
{
public:

inline void Add(T object)

Get rid of the 'inline' here.
 
K

Kai-Uwe Bux

Vincent said:
Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?


template<typename T> class ArrayPtr : public std::vector<T>
{
public:

inline void Add(T object)
{
push_back(object);
}

inline void Clear()
{
clear();
}

int GetCount()
{
return size();
}
};


The goal is to empty my vector and to deallocate pointer when I call
Clear().


What about:

template < typename T >
class ArrayPtr;
// no generic implementation !

template < typename T >
class ArrayPtr<T*> : public std::vector<T*>
// partial specialization for pointer types provided
{
// whatever
}


Do not provide a specialization for non-pointer types. You can add
specializations for smart-pointers as needed.


Best

Kai-Uwe Bux

ps.: public inheritance from std::vector is rarely a good idea. Your
particular need is a little unclear but it does not look like an exception
to the rule of thumb.
 
J

Jens Theisen

Vincent said:
I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?

See Fredericks posting, which works in principle (VerifyFuncDecl was
declared twice, so you can only use his macro once in a class definition).

If you want to delete pointers, you know they're C-style pointers, so
you can just take the value type as a template argument:

template<typename T> class ArrayPtr : public std::vector<T*>
{
public:
....

However, this is probably not something you want to do.

You generally not use delete but use libraries that do the management
for you. If you have access to boost or tr1, use a vector of shared_ptrs.

If not, build your own smart pointer or build the memory management into
a base class of your managed objects. Don't mess around with a memory
managed array unless you have some special reason to do it.

Jens
 
Z

zeppe

Kai-Uwe Bux said:
What about:

template < typename T >
class ArrayPtr;
// no generic implementation !

or even

template < typename T >
class ArrayPtr
{
private:
~ArrayPtr();
};

to have a build error instead of a link one.

In general, the best one is to let the object deallocate itself when no
more referenced (using a smart pointer), instead of adding this logic to
the container.

Bye,

Zeppe
 
P

peter koch

Vincent RICHOMME skrev:
Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?

When I originally saw your post, I thought in the same direction as
Kai-Uwe. But it is obvious to me now that Ian Collins solution is much
better. It is also coherent with e.g. std::auto_ptr (it is
std:auto_ptr<int> - not auto_ptr<int*>).
One exception is that I must agree that inheriting from std::vector is
a bad idea. And Jens Theisen is also correct that boost is a good
place to check out. I believe that they have not only shared_ptr but
also some pointer containers. Check that site out!

/Peter
 
J

Jarmo Muukka

Vincent RICHOMME said:
Hi,

I would like to create a class called ArrayPtr that could only store
pointers. How can I be sure that arguments passed is a pointer ?


template<typename T> class ArrayPtr : public std::vector<T>
{
public:

inline void Add(T object)
{
push_back(object);
}

inline void Clear()
{
clear();
}

int GetCount()
{
return size();
}
};


The goal is to empty my vector and to deallocate pointer when I call
Clear().

How about this?

template< typename T >
void ArrayPtr<T>::Clear()
{
int count = this->size();
while ( count )
// if you get a compilation error in here
// (C2541: 'delete' : cannot delete objects that are not pointers)
// it's because the type you're using to store in this array is not
a pointer type
// or the class does not have accessible destructor.
// Fix the problem in the class or use a different class.
delete this->operator[]( --count );

this->std::vector<T>::clear();
}

JMu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top