473,659 Members | 2,632 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problem: how to use one std container to store multiple types?

Hi.
Before all, please excuse me for bad english and for very newbie
questions. I hope to don't boring you.

I'm trying to write a very simple GUI using openGL.
So I'm writing some different widgets classes, like buttons, images,
slider, etc...

Each class has a draw() method.

The idea is to put all widget to draw in a vector, and after, in pseudocode:

-----------------------------
for each widget w in vector:
w.draw()
-----------------------------

So I should declare the vector, like

vector<widget> widgetList;

and this is my trouble: I've different classes (that has some common
methods, like draw(), on(), off() etc...) and I should put all in one
std container. It's possible?
Really I don't know even how to declare the vector. In example, if I've
the class

----------------------------
class foo {
private:
int width;
int height;
public:
int getWidth();
int getHeight();
};
----------------------------

how to declare a container for foo? Surely not writing

vector<foo> fooList;

Should I use typedef? Can you explain me this?

I know I'm a newbie and maybe these are very silly questions. However I
can't find these info on the books I'm reading (they are for beginners,
and don't write about STD) and the same using google.
Can you help me?

Thanks,
Manuel

Dec 27 '05 #1
20 5094
Manuel wrote:

I'm trying to write a very simple GUI using openGL. So I'm writing
some different widgets classes, like buttons, images, slider, etc...

Each class has a draw() method.

The idea is to put all widget to draw in a vector, and after, in
pseudocode:

----------------------------- for each widget w in vector: w.draw()
-----------------------------

Look at Design Pattern called Composite which can be used to wrap such
structure easily. GoF's book [1] includes case study very similar to
your problem so you may find this book intersting.

Simply, create abstract base class i.e. Widget and
inherit concrete (specialized) gadgets from the Widget.
Declare in Widget pure virtual method i.e. void draw(canvas)
and implement it in every concrete widget suitably.
Finally, store all widgets in a container through pointer to the base
class Widget (dynamic polymorphism).

So I should declare the vector, like

vector<widget> widgetList;

and this is my trouble: I've different classes (that has some common
methods, like draw(), on(), off() etc...) and I should put all in
one std container. It's possible?


Yes, do it as I explained above.
Here is simple implementation which should help to understand that idea:

#include <algorithm>
#include <iostream>
#include <vector>
////////////////////////////////////////////////////////////
struct DeleteObject
{
template <typename T>
void operator()(cons t T* ptr) const
{
delete ptr;
}
};
////////////////////////////////////////////////////////////
class Widget
{
public:
virtual void draw() const = 0;
virtual ~Widget() {}
};
class Button : public Widget
{
public:
void draw() const { std::cout << "Drawing Button" << std::endl; }
};
class Label : public Widget
{
public:
void draw() const { std::cout << "Drawing Label" << std::endl; }
};
class Slider : public Widget
{
public:
void draw() const { std::cout << "Drawing Slider" << std::endl; }
};

int main()
{
std::vector<Wid get*> v;
v.push_back(new Button());
v.push_back(new Label());
v.push_back(new Slider());
v.push_back(new Button());

std::vector<Wid get*>::const_it erator it;
for (it = v.begin(); it != v.end(); ++it)
{
(*it)->draw();
}

// Delete widgets
std::for_each(v .begin(), v.end(), DeleteObject()) ;

return 0;
}
////////////////////////////////////////////////////////////

[1] Design Patterns: Elements of Reusable Object-Oriented Software
by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 27 '05 #2
Mateusz Łoskot wrote:
Look at Design Pattern called Composite which can be used to wrap such
structure easily. GoF's book [1] includes case study very similar to
your problem so you may find this book intersting.

Simply, create abstract base class i.e. Widget and
inherit concrete (specialized) gadgets from the Widget.
Declare in Widget pure virtual method i.e. void draw(canvas)
and implement it in every concrete widget suitably.
Finally, store all widgets in a container through pointer to the base
class Widget (dynamic polymorphism).


Thanks you very much for the example!!

Some questions:

1) What happen if I use v.clear() instead DeleteObject() ??
2) In your example each class has the same number of methods. But what
happen if some classes have different numbers of methods? Should be not
a problem, right ??
3) Exist other way instead using a pointer in std::vector<Wid get*> v; ??

Again, thanks, THANKS!

Ciao,

Manuel
Dec 27 '05 #3
Manuel wrote:

Thanks you very much for the example!!

You're welcome!
Some questions:

1) What happen if I use v.clear() instead DeleteObject() ??
Look at older thread titled "STL map and memory management (clear() )",
about Dec, 15.
2) In your example each class has the same number of methods. But
what happen if some classes have different numbers of methods? Should
be not a problem, right ??
No problem. But remember that only common members may be accessed during
iterations (without casting). I mean, when iterating you "can see" all
widgets "through" base class interface - Widget.
Just a figurative explanation :-)
3) Exist other way instead using a pointer in std::vector<Wid get*> v;
??


In your particular solution I don't see anything better - abstract base
class allow you to access specialized types through unified interface
(declared in base class). I strongly recommend you to read GoF's
explanation of Composite, then may be you will get the idea behind it
more clear.

Note: you can use "smart pointers" instead of raw pointers. Then memory
management is much simplier. Here they are:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 27 '05 #4
Mateusz Łoskot wrote:
You're welcome! [...] Look at older thread titled "STL map and memory management (clear() )",
about Dec, 15. [...]I strongly recommend you to read GoF's
explanation of Composite, then may be you will get the idea behind it
more clear.

Note: you can use "smart pointers" instead of raw pointers. Then memory
management is much simplier. Here they are:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

THANKS!!
I'll study your suggestions and trying some experiments before boring
you with other newbie questions.:-)

Best Regards,

Manuel
Dec 27 '05 #5

Manuel wrote in message <43************ **********@read er1.news.tin.it >...
Mateusz Łoskot wrote:
Some questions:

1) What happen if I use v.clear() instead DeleteObject() ??


You would leave objects in memory with no way to delete them. If you want to
use 'v.clear()', you can do it this way:

int main(){
std::vector<Wid get*> v;
Button Btn;
v.push_back( &Btn );
Label Lbl;
v.push_back( &Lbl );
// .... etc. ....
std::vector<Wid get*>::const_it erator it;
for (it = v.begin(); it != v.end(); ++it){
(*it)->draw();
}

v.clear() // vector will empty at this point.
Label Lbl2;
v.push_back( &Lbl2 );
v.clear() // vector will empty at this point.
return 0;
} // Btn, Lbl, etc. destructors will be invoked at this point.

Also read what Mateusz suggested.

Bruce Eckel, in his book 'Thinking in C++' vol 2, has another way to handle
the pattern (which he calls the 'Command pattern' ). You can download a legal
copy of the book here: http://www.bruceeckel.com/ [ref: //:
C10:CommandPatt ern.cpp ]

--
Bob R
POVrookie
Dec 27 '05 #6
BobR wrote:
Bruce Eckel, in his book 'Thinking in C++' vol 2, has another way to handle
the pattern (which he calls the 'Command pattern' ). You can download a legal
copy of the book here: http://www.bruceeckel.com/ [ref: //:
C10:CommandPatt ern.cpp ]

Thanks...a lot of things to read :-)

POVrookie


Curiosity: Are you POVray user?

Ciao,

Manuel
Dec 27 '05 #7

Manuel wrote:
Mateusz Loskot wrote:
You're welcome!

[...]
Look at older thread titled "STL map and memory management (clear() )",
about Dec, 15.

[...]
I strongly recommend you to read GoF's
explanation of Composite, then may be you will get the idea behind it
more clear.

Note: you can use "smart pointers" instead of raw pointers. Then memory
management is much simplier. Here they are:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

THANKS!!
I'll study your suggestions and trying some experiments before boring
you with other newbie questions.:-)


I recommend you use a deep copy (clone) smart pointer, instead.
http://code.axter.com/copy_ptr.h
or a COW smart pointer
http://code.axter.com/cow_ptr.h

Both the copy_ptr and the cow_ptr can perform a deep copy when needed.
Example usage:
vector<copy_ptr <foo> > vFoo;
vFoo.push_back( new FooDerived);

You can use the boost::shared_p tr only if you're sure sharing the
pointee will not negatively effect your code. In most cases, this is
rarely what you want in a container.

Boost also has a set of pointer containers, but the interface is poor,
and does not match the STL containers very well.
I recommend using copy_ptr or cow_pt instead.

For more information, read the following related Article:
http://www.codeguru.com/cpp/cpp/algo...le.php/c10407/

In the above article it uses a clone_ptr smart pointer, but the
copy_ptr is a more optimize and complete version of the clone_ptr class.

Dec 27 '05 #8

Manuel wrote in message <43************ **********@read er3.news.tin.it >...
BobR wrote:
Bruce Eckel, in his book 'Thinking in C++' vol 2, has another way to handle the pattern (which he calls the 'Command pattern' ). You can download a legal copy of the book here: http://www.bruceeckel.com/ [ref: //:
C10:CommandPatt ern.cpp ]


Thanks...a lot of things to read :-)

POVrookie


Curiosity: Are you POVray user?


Yes. I am still a POVray rookie because I have been spending more time
learning C++.
One of my current projects is for POVray (though it also outputs OGL, RAW,
RAD, OBJ, TIN, RIB). It makes a 3D Rock (as triangle mesh) and
displays/animates in a OpenGL window in wxWidgets.

Some people think that POV is Point-Of-View, and I just answer them with a
smiley-face :-}

--
Bob R
POVrookie
--
POVray: http://www.povray.org/
Dec 27 '05 #9
Can you explain me (please be patient) because this structure

struct DeleteObject
{
template <typename T>
void operator()(cons t T* ptr) const
{
delete ptr;
}
};

instead a function like

DeleteObject( *ptr){ delete ptr; };

??

Thanks,

Manuel
Dec 28 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
1604
by: Merlin | last post by:
Hi Imagine the following classes (A class diagram will help) BASE, A, B, C, D, E, F, G. A, B, C, D, G inherit from BASE. E, F inherit from D.
8
2419
by: Markus Dehmann | last post by:
I defined a base class in order to put heterogeneous values into a standard container: All values that I store in the container are derived from my base class. Now when I iterate over the elements of the container and want my original values back - can I avoid excessive casting and if statements? (see my sample code below.) Can I make it more elegant? #include <iostream> #include <vector>
4
2396
by: Leslaw Bieniasz | last post by:
Cracow, 20.09.2004 Hello, I need to implement a library containing a hierarchy of classes together with some binary operations on objects. To fix attention, let me assume that it is a hierarchy of algebraic matrices with the addition operation. Thus, I want to have a virtual base class class Matr;
5
1647
by: Johan | last post by:
Hi, Hi like to create a linked list with a template class ( see below ). How to make one using the STL container list. I want to create a linked list with different kind of types i.e. DataVariant<int>, DataVariant<string> etc, etc #include <list>
0
3931
by: Lokkju | last post by:
I am pretty much lost here - I am trying to create a managed c++ wrapper for this dll, so that I can use it from c#/vb.net, however, it does not conform to any standard style of coding I have seen. It is almost like it is trying to implement it's own COM interfaces... below is the header, and a link to the dll+code: Zip file with header, example, and DLL:...
7
2912
by: jsale | last post by:
I'm currently using ASP.NET with VS2003 and SQL Server 2003. The ASP.NET app i have made is running on IIS v6 and consists of a number of pages that allow the user to read information from the database into classes, which are used throughout the application. I have made class collections which, upon reading from the DB, create an instance of the class and store the DB values in there temporarily. My problem is that if user1 looks at...
21
3658
by: aaragon | last post by:
Hello everyone, I would like to know if there is a way to use the std::map to store different types for one of its two types. That is, I'm trying to use it as: typedef std::map<string,doubleMap; but instead of double, I have integers, even booleans so I guess that the use of double waste a lot of storage. Is there any way to do this?
16
2687
by: PeterAPIIT | last post by:
Hello all C++ expert programmer, i have wrote partial general allocator for my container. After reading standard C++ library and code guru article, i have several questions. 1. Why allocator write forward declaration then allocation for void* rather than directly wrote allocator first ?
9
3107
by: raylopez99 | last post by:
Hello all Im trying to get the below to work and cannot get the format right. Its from this example: http://msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx What it is: Im trying to store multicast delegates in a hash table, and then fire the delegates one of two ways (after registering/ creating the delegates, etc).
0
8341
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8751
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8539
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8630
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4176
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4342
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2759
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1982
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.