BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Vector of TPanels?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++)
View previous topic :: View next topic  
Author Message
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 5:09 pm    Post subject: Vector of TPanels? Reply with quote



I want to create a vector of TPanels that I dynamically create with a
press of a button. I then want to dynamically delete them and not leave
a whole in the vector list. I have successfully done this with simple
integers but I am having problems with TPanels. This is the syntax I
used for the integers and it worked:

int *tempX = m_PointsX.begin()+5;//delete the fifth element
m_PointsY.erase(tempY);

My TPanel vector does not have a begin() and end() so I tried it with
front() but I get errors when I compile:

TPanel* temp = m_Points.front()+5;
m_Points.erase(temp);

How do I go about erasing the 5th element from this vector? Any ideas?
Where have vectors been my whole life, there great!
Back to top
Alisdair Meredith
Guest





PostPosted: Sat Mar 26, 2005 6:02 pm    Post subject: Re: Vector of TPanels? Reply with quote



Rory Walsh wrote:

Quote:
This is the syntax I used for the integers and it worked:

int *tempX = m_PointsX.begin()+5;//delete the fifth element
m_PointsY.erase(tempY);

However, it is not guaranteed to work on all implementations. You have
made a (reasonable) assumption that vector iterators will be simple
pointers. vector is deliberately designed so this is possible, but it
is not required. Many other standard libraries usea specific type for
vector::iterator, that can support extra options when debugging.

The 'correct' way to write this would be:

vector<int>::iterator tempX = m_PointsX.begin()+5;
m_PointsY.erase(tempY);

If you use vector<int>::iterator a lot, you may want to create a
typedef for it!

Also note that many standard algorithms are function templates, so they
will automatically deduce the correct type for you, simply by passing
the arguments. This means that in my code, I rarely see the iterators
named:

m_PointsY.erase( m_PointsX.begin() + 5 );


Quote:
My TPanel vector does not have a begin() and end() so I tried it with
front() but I get errors when I compile:

Uh oh, this sounds a bit wierd!
Could you show me the code you use to fill your
vector<TPanel *> with panels?


AlisdairM(TeamB)

Back to top
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 6:34 pm    Post subject: Re: Vector of TPanels? Reply with quote



I basically have a button that does this each time I press it

{
m_Points[incr] = new TPanel(Image1);
m_Points[incr]->Parent = Panel1;
incr++;
}

I have left out the other stuff for clarity, but that basically it? Is
this ok?


Alisdair Meredith wrote:
Quote:
Rory Walsh wrote:


This is the syntax I used for the integers and it worked:


int *tempX = m_PointsX.begin()+5;//delete the fifth element
m_PointsY.erase(tempY);


However, it is not guaranteed to work on all implementations. You have
made a (reasonable) assumption that vector iterators will be simple
pointers. vector is deliberately designed so this is possible, but it
is not required. Many other standard libraries usea specific type for
vector::iterator, that can support extra options when debugging.

The 'correct' way to write this would be:

vector<int>::iterator tempX = m_PointsX.begin()+5;
m_PointsY.erase(tempY);

If you use vector<int>::iterator a lot, you may want to create a
typedef for it!

Also note that many standard algorithms are function templates, so they
will automatically deduce the correct type for you, simply by passing
the arguments. This means that in my code, I rarely see the iterators
named:

m_PointsY.erase( m_PointsX.begin() + 5 );



My TPanel vector does not have a begin() and end() so I tried it with
front() but I get errors when I compile:


Uh oh, this sounds a bit wierd!
Could you show me the code you use to fill your
vector<TPanel *> with panels?


AlisdairM(TeamB)

Back to top
Alisdair Meredith
Guest





PostPosted: Sat Mar 26, 2005 7:10 pm    Post subject: Re: Vector of TPanels? Reply with quote

Rory Walsh wrote:

Quote:
I basically have a button that does this each time I press it

{
m_Points[incr] = new TPanel(Image1);
m_Points[incr]->Parent = Panel1;
incr++;
}

I have left out the other stuff for clarity, but that basically it?
Is this ok?

It depends on whether or not you have pre-filled your vector with null
pointers. I would prefer to do this with

m_points.push_back( new TPanel(Image1) );

This expands the vector by 1 element, and puts the panel in it.

Likewise, to remove the last element of the vector:

m_points.pop_back();


If you have not filled your vector in the constructor, then your calls
to m_points[] above would be the same as indexing from an array you
have not allocated:

int *x; // = new int[5] missing
x[3] = 5; // Oops!


Note that while you can put pointers in and out of vector quite easily,
you still need to manage the memory. Ultimately, everything that is
newed should be deleted.

In your case you will not leak memory, as the VCL library will
guarantee all your panels are deleted when their owner, Image1, is
destroyed. However, if Image1 is deleted before your vector, you will
have a vector full of invalid pointers!

THat is why I use the shared_ptr 'smart pointer' from the Boost
library. This class acts just like a pointer, but also wraps that
pointer with a reference count. When the last shared_ptr holding onto
a pointer dies, it calls delete.

Take a look at www.boost.org for details, but beware. The whole
library has grown quite big and scary over the years!

AlisdairM(TeamB)

Back to top
Duane Hebert
Guest





PostPosted: Sat Mar 26, 2005 7:21 pm    Post subject: Re: Vector of TPanels? Reply with quote


"Alisdair Meredith" <alisdair.meredith@no-spam-splease (AT) uk (DOT) renaultf1.com> wrote


Quote:
Take a look at www.boost.org for details, but beware. The whole
library has grown quite big and scary over the years!

Quite big, I agree with Alisdair. What's scary are the
years that I didn't use it <g>



Back to top
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 8:05 pm    Post subject: Re: Vector of TPanels? Reply with quote

Thanks for the pointers, pardon the pun! I'll keep grafting away at it.
It's making more sense now. I can't believe that I have never used
vectors before? Cheers,
Rory.




Duane Hebert wrote:
Quote:
"Alisdair Meredith" <alisdair.meredith@no-spam-splease (AT) uk (DOT) renaultf1.com> wrote



Take a look at www.boost.org for details, but beware. The whole
library has grown quite big and scary over the years!


Quite big, I agree with Alisdair. What's scary are the
years that I didn't use it


Back to top
Alisdair Meredith
Guest





PostPosted: Sat Mar 26, 2005 8:40 pm    Post subject: Re: Vector of TPanels? Reply with quote

Rory Walsh wrote:

Quote:
Thanks for the pointers, pardon the pun! I'll keep grafting away at
it. It's making more sense now. I can't believe that I have never
used vectors before? Cheers, Rory.

I thoroughly recommend this book:
http://www.josuttis.com/libbook/

as the easiest way of learning and appreciating the C++ Standard
Library. Getting your head around separate containers, iterators and
algorithms takes a little getting used to, and it a bit of a
chicken-and-egg situation. Until you get a feel for all 3, you will
not understand any of them!

Nico's book introduced them well, along with several easy to use
motivating examples. I can't recommend it highly enough.

AlisdairM(TeamB)

Back to top
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 9:41 pm    Post subject: Re: Vector of TPanels? Reply with quote


Quote:
m_points.push_back( new TPanel(Image1) );

This expands the vector by 1 element, and puts the panel in it.

I had also been setting the attributes of each TPanel as I created them,
for example I was doing this:

m_Points[incr] = new TPanel(Image1);
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

If I now do this:

m_points.push_back( new TPanel(Image1) );
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

I get some strange errors. Originating from the line where I specify the
parent?

Ideally I would prefer to use method you suggested as I can create a
leftmost and rightmost panel and then insert the rest between them.
Otherwise there is not much difference between this and an array? Any
ideas?

Back to top
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 10:21 pm    Post subject: Re: Vector of TPanels? Reply with quote

Actually it compiles alright but I get a fatal exception when I create a
new panel dynamically.
Quote:

m_points.push_back( new TPanel(Image1) );

This expands the vector by 1 element, and puts the panel in it.


I had also been setting the attributes of each TPanel as I created them,
for example I was doing this:

m_Points[incr] = new TPanel(Image1);
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

If I now do this:

m_points.push_back( new TPanel(Image1) );
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

I get some strange errors. Originating from the line where I specify the
parent?

Ideally I would prefer to use method you suggested as I can create a
leftmost and rightmost panel and then insert the rest between them.
Otherwise there is not much difference between this and an array? Any
ideas?

Back to top
Rory Walsh
Guest





PostPosted: Sat Mar 26, 2005 11:31 pm    Post subject: Re: Vector of TPanels? Reply with quote

I seem to be going round in circles here. If I explain what I am trying
to do perhaps someone can tell me if I am going about it the right way?
First I create a simple line going from the bottom right corner of a
canvas to the bottom left corner of a canvas. Each time I click on the
canvas a new panel will be created and the line will connect from the
two corners to the panel position. If I create another panel somewhere
on the canvas between an existing panel and the corner a line will
connect between them. A little like an elastic on a notice board. My
idea was to create a vector of panels and each time I create a new panel
between any other two it would simple jump into the vector list between
the other two panel. This just makes drawing the lines a whole lot
easier. Is a vector list the best way to do this? And can I insert
panels anywhere into a vector list? It all going okay until I try to
delete the panels by right-clicking! Cheers,
Rory.




Rory Walsh wrote:
Quote:
Actually it compiles alright but I get a fatal exception when I create a
new panel dynamically.


m_points.push_back( new TPanel(Image1) );

This expands the vector by 1 element, and puts the panel in it.



I had also been setting the attributes of each TPanel as I created
them, for example I was doing this:

m_Points[incr] = new TPanel(Image1);
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

If I now do this:

m_points.push_back( new TPanel(Image1) );
m_Points[incr]->Parent = Panel1;
m_Points[incr]->Left = 1;
m_Points[incr]->Top = Image1->Height-8;
m_Points[incr]->Width = 10;
m_Points[incr]->Height = 10;
m_Points[incr]->BevelInner = true;

I get some strange errors. Originating from the line where I specify
the parent?

Ideally I would prefer to use method you suggested as I can create a
leftmost and rightmost panel and then insert the rest between them.
Otherwise there is not much difference between this and an array? Any
ideas?

Back to top
Duane Hebert
Guest





PostPosted: Sun Mar 27, 2005 1:14 am    Post subject: Re: Vector of TPanels? Reply with quote


"Rory Walsh" <rorywalsh (AT) ear (DOT) ie> wrote

Quote:
I seem to be going round in circles here. If I explain what I am trying
to do perhaps someone can tell me if I am going about it the right way?
First I create a simple line going from the bottom right corner of a
canvas to the bottom left corner of a canvas. Each time I click on the
canvas a new panel will be created and the line will connect from the
two corners to the panel position. If I create another panel somewhere
on the canvas between an existing panel and the corner a line will
connect between them. A little like an elastic on a notice board. My
idea was to create a vector of panels and each time I create a new panel
between any other two it would simple jump into the vector list between
the other two panel. This just makes drawing the lines a whole lot
easier. Is a vector list the best way to do this? And can I insert
panels anywhere into a vector list? It all going okay until I try to
delete the panels by right-clicking! Cheers,
Rory.

There's no vector list. You seem to be trying to use a std::vector.
A vector is similar to a variable sized array. It can be accessed
by iterator or index. In order to allow access by index, the data it
holds must be ordered. If you want to add to the end of a vector, it
works well. If you want to insert into the middle, it has to copy
everything from the middle to the end and append after the insert.

A std::list is a list. It can't be accessed via an iterator. It has to
be traversed. It doesn't have to maintain sequential members
so inserting/deleting from the middle is less expensive.

You can achieve what you want with a vector but you have to
be aware of the complexity. If you're just storing pointers,
you could init the vector with some number of null pointers. When
you build your panel, find that index and create a new panel. When
it goes away, find the index and delete the pointer, then set it to null.

In your initial example, you seemed to be trying to use the index
but you weren't filling it up with null pointers first. Allisdair tried to
point this out to you, then suggested a better way would be to use
push_back. This would be my suggestion as well but you would need to still
find the index in the vector to delete it. I don't remember if TPanel has a tag
property but you could use that to store it.

Your last post was asking about how to use the panel after pushing it
into the vector. You can get the last member with back(). You can get
it's index by size() - 1. Look at the list of members for std::vector.
You could also create the pointer first and then push it into the vector
after you set everything. You could derive a class from your panel,
add a constructor that does everything that you want like setting the
parent etc. It's hard to say which is best for you.

Keep posting questions when you get stuck, but I would suggest
some reading as well.

HTH



Back to top
Duane Hebert
Guest





PostPosted: Sun Mar 27, 2005 2:24 am    Post subject: Re: Vector of TPanels? Reply with quote


"Duane Hebert" <spoo (AT) flarn2 (DOT) com> wrote

Quote:
A std::list is a list. It can't be accessed via an iterator. It has to

this of course should say via an index.



Back to top
Rory Walsh
Guest





PostPosted: Mon Mar 28, 2005 11:07 am    Post subject: Re: Vector of TPanels? Reply with quote

Cheers, between your help and the info I have found on the web its
becoming clearer(albeit slowly!). Following your last post I was able to
achieve exactly what I wanted to do(thanks), apart from one thing. I
want to use the 'insert' member function of vector. I tried the following:

m_Points.insert(m_Points.size()-5, new TPanel(Image1));

where "m_Points.size()-5" is the position I want to place the new
TPanel. I get the error:

[C++ Error] Unit1.cpp(100): E2285 Could not find a match for
'_STL::vector<TPanel *,_STL::allocator::insert(unsigned
int,undefined)'

The tests I ran with an integer vector worked fine, for example

scores.insert(scores.begin()-5, 540);

With regards your previous post I also changed my code so now in the
Form constructor I filled the panel vector with NULL pointers. Cheers,
Rory.


Duane Hebert wrote:
Quote:
"Duane Hebert" <spoo (AT) flarn2 (DOT) com> wrote


A std::list is a list. It can't be accessed via an iterator. It has to


this of course should say via an index.



Back to top
Duane Hebert
Guest





PostPosted: Mon Mar 28, 2005 12:08 pm    Post subject: Re: Vector of TPanels? Reply with quote


"Rory Walsh" <rorywalsh (AT) ear (DOT) ie> wrote

Quote:
Cheers, between your help and the info I have found on the web its
becoming clearer(albeit slowly!). Following your last post I was able to
achieve exactly what I wanted to do(thanks), apart from one thing. I
want to use the 'insert' member function of vector. I tried the following:

m_Points.insert(m_Points.size()-5, new TPanel(Image1));

where "m_Points.size()-5" is the position I want to place the new
TPanel. I get the error:

[C++ Error] Unit1.cpp(100): E2285 Could not find a match for
'_STL::vector<TPanel *,_STL::allocator::insert(unsigned
int,undefined)'

The tests I ran with an integer vector worked fine, for example

scores.insert(scores.begin()-5, 540);

In the second case, you're using an iterator. In the first, you're
using an index. Have you tried using an offset from begin() for
your table insert?

From dinkumware.com c++ reference:

vector::insert
iterator insert(iterator where, const Ty& val);
void insert(iterator where, size_type count, const Ty& val);
template<class InIt>
void insert(iterator where, InIt first, InIt last);



Back to top
Duane Hebert
Guest





PostPosted: Mon Mar 28, 2005 12:50 pm    Post subject: Re: Vector of TPanels? Reply with quote


"Duane Hebert" <spoo (AT) flarn2 (DOT) com> wrote

Quote:

"Rory Walsh" <rorywalsh (AT) ear (DOT) ie> wrote


Quote:
scores.insert(scores.begin()-5, 540);

I just noticed the -5 here. Are you sure this is doing
what you expect?

If you have some max size of tables, why not just
build that to begin with with 0 pointers and create
or delete them as needed. It may be simpler
than dealing with insert/delete.

Also, if I was trying this I would probably start with
a std::vector<boost::shared_ptr and use
reset() to hide show the panels. Though using standard
containers with VCL objects may take some extra
care when dealing with owners and parents being
destroyed.

Good luck.



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Language C++) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.