C++/CButtons

Advertisement


Question
Im programming using visual c++, and have started a MFC project. I want to be able to run through a for loop and initialise how many buttons the users wants displayed (CButtons). For an example my code at the moment asks the users how many buttons they want, if the user wants 5 buttons it then runs the line of code:

CButton myButton;

5 times. From what I can see this works ok, but is there a better way of doing this? Should I be using a linked list? Also, because each object I create of type CButton is called myButton, how to I 'talk' to each button when I want to chnage something, if every button I created has the same 'myButton' name? like say the text on the button.

If anyone could help me it would be greatly appreciated.

cheers


Answer
I suppose you have something like:

       for ( int i=0; i<numberOfButtons; ++i )
       {
         CButton myButton;
       // ...
       }

There are several problems here. First, each time through the loop a CButton object is created on the stack and then destroyed at the end of the loop iteration - calling the CButton destructor which destroys the button window viz:

       CButton::~CButton()
       {
         DestroyWindow();
       }

(from winctrl1.cpp).

I think you would want them to exist for a little longer. Second, the way you are approaching the creation a collection of objects is not really the way it should be done.

If you wish to create a collection of objects then use a collection (or container) type. The most obvious one is a built in array, in this case, of CButton objects:

       CButton buttons[5];

You can then refer to each button in the array using its index, starting from index 0 (not 1):

       buttons[0] // first button object in the array
       buttons[4] // last button object in the array

You can also use a variable of integer type for the index:

       for ( int i=0; i < 5; ++i )
       {
         InitialiseButton( buttons[ i ] );
       }

Note that I have used the 'magic number' 5 twice now: once to declare the array size and once to specify the end of the loop. However 5 on its own has no real meaning - it is not clear that the 5 used to terminate the loop is definitely linked to the 5 that is the size of the array. A better approach would be to define a named constant for this value:

       const int NumberOfButtons( 5 );

and use this instead:

       CButton buttons[ NumberOfButtons ];

// ...

       for ( int i=0; i < NumberOfButtons; ++i )
       {
         InitialiseButton( buttons[ i ] );
       }


This brings us to the problem with this scheme for your case. That is, the number of elements in the array has to be known at compile time, and your program will only have this information at runtime. To get around this you use a dynamic array, creating the objects on the heap using the new operator and then destroying them later with the delete operator. As we wish to create an array dynamically we have to use the array forms of both new and delete:

       CButton * buttons = new CButtons[numberOfButtons];

// Elsewhere:

       delete [] buttons;  // NOTE: Array form of delete

Notice that we get a pointer to the first object (element 0) of the array returned. In C and C++ there is a strong link between pointers and arrays, so we can still use this as an array as before:

       buttons[ 2 ]

Now the MFC and the C++ standard library both contain class templates for various collection types that make it easier to manage collections of objects such as arrays (or vectors for the C++ standard library), linked lists (which you mention) and maps. They have different properties.

Note: I assume you are using a fairly recent version of Visual C++ - version 5, 6, .NET, .NET 2003 or .NET 2005.

Arrays and vectors (another name for a one dimensional array) assume contiguous memory and are for fast random access to existing elements - however adding new elements is only really practical at the end and may require copying the whole of the existing array to a new, larger, block of memory. Inserting or removing items in the middle of the array means all items below the point of insertion or removal have to shuffled up or down - requiring much copying of elements.

Linked lists allow easy addition and removal of items anywhere in the list but you have to step through the list from one end or the other (if it is double linked then you can start at either end) until you find the item you require.

Maps (sometimes called dictionaries) are associative. They associate a value with a key - so for example you could associate your buttons with a string name. In this case the name would be the key and the button associated with that name the value.

I will not go into the ins and out of these types here as the details would go on for a very long time and you can look up the various topics in the MFC and C++ library documentation and various books and other resources.

For the MFC collection types look for the class templates CArray, CList, CMap and CTypedPtrArray, CTypesPtrList and CTypedPtrMap (taken from an MFC 6.0 class hierarchy poster I have on my wall!). There are also a load of specific array, list and map types such as CStringArray, CPtrList and CMapStringToOb based on CArray, CList and CMap.

If you do not have the MFC documentation to hand then you should be able to find it online at http://www.msdn.microsoft.com/ under the Library menu item.

The C++ standard library is documented in various books and some reference information can be found online - for example at http://www.sgi.com/tech/stl/. The book I use is "The C++ Standard Library a Tutorial and Reference" by Nicolai M. Josuttis. You  need to look for the container types such as vector, list, map, set, deque etc.. Note that some versions of the C++ library have additional, non-standard, container types - hash_map for example - and such types may not exist or differ between various implementations of the library.

Finally I would get yourself a good set of C++ tutorial and reference books - you obviously have not bothered much with learning the language and this will cause you much pain - C++, like C, is a very powerful tool, but unlike some programming environments it assumes you are all grown up and know what you are doing. If you wish to shoot yourself in the foot, so to speak, then C++ will not prevent you from doing so.

If you are just interested in doing simple GUI projects then maybe you should look at other options like Visual Basic, C#, or maybe even Java.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.