|
| kempofighter (525) | |||
| Admittedly there are many tutorials around for beginners. The purpose of this article is not to provide yet another. Instead its purpose is to make a case for why beginners should prefer the std containers and algorithms over hand written copycats. Actually, we all should prefer std solutions when writing object oriented C++ code. The target audience is anyone who has been learning C++ and who has a basic understanding of language syntax, especially regarding instantiation of structures and classes, as well as declaring and calling functions. First let me summarize the advantages of learning the std containers and algorithms during the early stages of your development. 1) You'll avoid lots of common mistakes when writing for loops and if statements and the chances of your program containing annoying defects decreases significantly. 2) There is a good chance that the std::algorithms are faster then your own handwritten loops or functions anyway. These are written by very intelligent people who have a lot more information about the inner workings of the compiler and the language itself. 3) Using building blocks will allow you to construct a program much faster. Instead of reinventing the wheel, learn to use the building blocks to accomplish your goals. You'll be able to spend more time studying and implementing your program's requirements. 4) You'll avoid nasty memory management gotchas. Although everyone must learn memory management eventually, allowing the std containers to do this for you will allow you to get some programs up and running without having to worry about managing dynamic memory. Memory management is a complex subject and can overwhelm a beginner. Do as little of it as possible, at first. Let me start by stating that this website does have a pretty good tutorial for the C++ language as well as for the std libraries. The examples are typically complete so that you can compile and execute them in your own compiler. Finding a good compiler and learning to use its debugger is a large part of the battle when learning C++. Stepping through a program with a debugger is a great way to analyze a program and learn from it. The examples that I am posting have been compiled using Microsoft Visual C++ express 2008. http://www.microsoft.com/express/vc/ Now, let's start by taking a look at some examples. The best way to learn, in my opinion, is to analyze existing code and write new test code that exercises the existing building blocks. If you know how to call a function, then you also know how to use a std algorithm. Don't let the word algorithm fool you into thinking that they are too complicated for beginners. Consider std::count. Here we use std::count to count the number of 1s in the array. It is a template function so std::count works with arrays or std containers such as deque and vector. It can also work with custom containers and iterators because it is a template function. In this case, the pointer to the first element of the array is the begin iterator while the pointer to one past the end of the array is the end iterator (remember that arrays are zero based).
Can you spot the errors in the above example? That program actually ran on my computer although incorrectCustomCounter produced an incorrect result. The program could have simply crashed. If I had simply used std::count, not only would the code have looked nicer but it would have worked correctly. Moreover, using std::count is as simple as making a function call. There is no reason to write your own counting function. std::count also provides a version that takes a predicate. Once you learn how to write predicates, the std::count becomes even more useful. Now you can extend the algorithm's capabilities even further! http://cplusplus.com/reference/algorithm/count/ http://cplusplus.com/reference/algorithm/count_if/ | |||
| kempofighter (525) | |||
| Now let's take a look at a more complex example. I have noticed that many beginners post threads that have to do with simple database tasks such as managing student or customer records. This example builds a dynamic array of student records and shows how the std algorithms can be used to manipulate, sort, and search the records with very little effort and few user defined loops. It also shows how you as a beginner could write a test application to learn how the algorithms and containers work.
You'll notice a couple of things about that example. First, I did not need to dynamically allocate memory directly. Therefore there is no chance of a memory leak in this program. There is no chance that I have deleted memory incorrectly, left any dangling references to objects, or used an uninitialized pointer. Second, it contains very few user defined for loops for collecting metrics, sorting, or printing the data. Although this website provides documentation for each algorithm, it is nice to pull some things together into one example to see how they can work together. So give it a try! Copy and paste it into a project and try fiddling with it yourself. If you write any useful adaptations, feel free to post them until the thread is archived. References: http://cplusplus.com http://cplusplus.com/reference/std/ http://cplusplus.com/reference/algorithm/ http://cplusplus.com/reference/stl/ http://cplusplus.com/reference/string/ Effective STL, 50 Specific Ways to Improve Your Use of the Standard Template Library, Scott Meyers The C++ Standard Library, A Tutorial and Reference, Nicolai M. Josuttis | |||
Last edited on | |||
| Duoas (2964) | |
| Very nice! You might want to give a little more information on just what exactly a 'functor' is (those confuse people -- so at least a link or two to learn more is good). I would also add a comment in the class definition itself as to why exactly the < operator is important. +1 | |
| jsmith (3099) | |||||||
For the advanced beginner (oxymoron intended), you could also write all of the above function objects as simple lambda expressions. For example, IsFromSanDiego can be written as:
IsTakingCalculus:
Example:
| |||||||
| kempofighter (525) | |
| Thanks for the feedback so far. I was limited in characters, and the example ended up being a bit long. I'll take the comments into consideration and post an update with some additional tips this evening. For now, I added a comment above operator<. I noticed that I forgot to write a comment for that. | |
| kempofighter (525) | |||
| I added a comment to the example explaining the point of operator< used for sorting. Duos mentioned adding some info about the functors. I've decided that to really explain functors well another article is necessary. Actually many articles could be written about functors. So let us keep it simple and explain the basic concept as it relates to this article. First, functors are classes that define the operator() and can be used as callbacks needed by the std algorithms, among other things. In my examples I used functors as callbacks in order to customize the std algorithms. This was one of the easier ones that I wrote:
Notice that the functors are written using the struct keyword instead of class. This is very common. Writing a functor should be simple and since members are public by default it is much easier to write them as a struct rather than a class. Also, the base class functors in the std library <functional> header are written as structs. Here are a couple of articles that I found to be useful while I was learning about functors. http://en.wikipedia.org/wiki/Function_object This one is interesting because it allows you to implement a functor in terms of another by simply negating an existing functor. It shows why it is more useful to design callbacks as functors rather than simply using a global or static member function. You can't pass "!isOdd" as the third argument to count_if because it is illegal syntax. By inheriting from a built in unary functor you have the ability to take advantage of some other useful tools built into the language such as not1. In the beginning, it is very easy to get into the habit of writing predicates or callbacks as global functions because it seems easier at first. If you get in the habit of writing functors you will be better off, although the payoff might not be obvious at first! http://cplusplus.com/reference/std/functional/not1/ | |||
This topic is archived - New replies not allowed.
