You are not logged in.

#1 2006-10-24 01:30:04

dhasenan
Member
Registered: 2006-10-11
Posts: 9

C++ classes: initialization rather than constructors?

Hey all--

I'm creating a C++ class for a circular array. (The Standard Template Library does not define one.) Most container classes in STL don't require you to call a constructor, and of course constructors return pointers, which means you either have to use placement new or dereference the return value of the constructor or suck it up and use pointers.

Clearly, there's a way to do this, since the STL does it. I could lift the technique from the STL, except it tends to be complex and unreadable and poorly indented. Besides which, for instance in the STL deques, the comments on the deque class claim that the associate _Base class initializes the memory, whereas the comments on the _Base class claim that it doesn't, and I see nothing in either that would do so.

All I want to do is set a couple of default values and allocate some memory. Anyone know how?


It's my fault.

Offline

#2 2006-10-24 02:09:36

yankees26
Member
From: Connecticut, USA
Registered: 2006-09-29
Posts: 190

Re: C++ classes: initialization rather than constructors?

If you mean that the STL doesn't call the constructor of the type in the template, like vector<string>, the string constructor isn't called, then: I believe it is done by using STL's allocator template class.

Offline

#3 2006-10-24 10:29:08

drakosha
Member
Registered: 2006-01-03
Posts: 253
Website

Re: C++ classes: initialization rather than constructors?

I do not understand the question... *Default* constructor is called whn you write

vector<int> vi;

Offline

#4 2006-10-24 15:07:08

phrakture
Arch Overlord
From: behind you
Registered: 2003-10-29
Posts: 7,879
Website

Re: C++ classes: initialization rather than constructors?

Ok, I need to clarify alot of this:

dhasenan wrote:

Most container classes in STL don't require you to call a constructor

False.  Constructors are always called.  C++ is not java and does not require () for a default (or empty) consructor.

dhasenan wrote:

and of course constructors return pointers

No.  They do not.  Constructors initialize an object of already allocated memory.  new returns a pointer, malloc returns a pointer, many things return a pointer.. constructors do not.

dhasenan wrote:

which means you either have to use placement new or dereference the return value of the constructor or suck it up and use pointers.

this doesn't make sense.

dhasenan wrote:

All I want to do is set a couple of default values and allocate some memory. Anyone know how?

const int DEFAULT_ALLOC_SIZE = 32;

template <typename>
class Foo
{
   T* t;
   public:
      Foo() : t(new T[DEFAULT_ALLOC_SIZE]) {}
      Foo(int n) : t(new T[n]) {}
};

Foo f; //32 elements
Foo g(10); //10 elements

Offline

#5 2006-10-27 07:07:17

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: C++ classes: initialization rather than constructors?

A circular array is an array, but not all the arrays are circular arrays. This is the relation you can easily make with a derivation. Make a new class derivated from vector (just study vector's template parameters) and reimplement iterators and some operators.

In a circular array you have no difference between .operator[]() and .at(). You always have to check the limits (as usually only .at does) and instead of throwing a exception calculate the right position:

In this little explamples 'position' is an int with the asked position,'size' is an int with current size of the vector.
if position is non negative the right position is:
position = position % size

if position is negative the right position is:
while (position < 0) position += size

about ++ and -- in the iterators:
++
position = (position +1) % size

--
position = (position + size -1) % size //The sum is there to avoid problems with 0

Probably you want override the operator[] also of iterators...

This way you remplement only few metods and you are there. Moreover you won't have problems of memory leaks, pointers, and (sorry) bugs related to your strange knownledge of C++,


About the main question of the topic that does not make sense IMO since you should do as I told. If you dislike the right and elegant phrakture's solution you can just using new to allocate 'chars' (sizeof(chars) == 1), reinterpret_cast to the type you want and call the costructor when you want.

Offline

#6 2006-10-27 20:06:26

bboozzoo
Member
From: Poland
Registered: 2006-08-01
Posts: 125

Re: C++ classes: initialization rather than constructors?

ezzetabi wrote:

A circular array is an array, but not all the arrays are circular arrays. This is the relation you can easily make with a derivation. Make a new class derivated from vector (just study vector's template parameters) and reimplement iterators and some operators.

Avoid inheriting from STL containers, they have non-virtual destructor what may cause problem in certain situations when you only have a pointer to vector, then destructor of derived class will not be called.

Offline

#7 2006-10-27 20:37:03

phrakture
Arch Overlord
From: behind you
Registered: 2003-10-29
Posts: 7,879
Website

Re: C++ classes: initialization rather than constructors?

bboozzoo wrote:

Avoid inheriting from STL containers, they have non-virtual destructor what may cause problem in certain situations when you only have a pointer to vector, then destructor of derived class will not be called.

Yes.  Standard Library containers are not meant to be base classes.  If you need "circular" access to, say, a vector, one can easilly do:

template <typename> //phpbb is removing "typename ContainerT"
ContainerT::iterator circular_next(ContainerT& container, ContainerT::iterator& it)
{
   ++it;
   if(it == container.end()) it = container.begin();
   return it;
}
...
std::vector<int> vec(10,1);
std::vector<int>::iterator it = vec.begin();

for(int i=0; i<100; ++i)
{
   std::cout << *it << std::endl;
   it = circular_next(vec, it);
}

NOTE: that function works with any standard library container

Offline

#8 2006-10-27 21:03:50

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: C++ classes: initialization rather than constructors?

OPS... Sorry, I forgot vectors do not use virtual members. Maybe u can still privately hinerit?

Offline

#9 2006-10-27 21:26:29

phrakture
Arch Overlord
From: behind you
Registered: 2003-10-29
Posts: 7,879
Website

Re: C++ classes: initialization rather than constructors?

You should _never_ derive from standard library containers.  This is not java.  Not everything needs a base class of a base class.

While, in some cases, it may be safe to do it, it is poor form.  If you need a class that acts-like a vector, use the "has-a" idiom in place of the "is-a" idiom, or simply create your own using the standard container concept.

Decent article on the topic is here:
http://uk.builder.com/programming/c/0,3 … 440,00.htm

But still, why would you create a new class when the function I defined above is 5 lines of code and works for ALL standard library containers... you could have a circular std::map<std> if you wanted to.

Offline

Board footer

Powered by FluxBB