分类: C/C++
2011-05-03 12:57:50
Other Formats of this Document
(The latest version of this document is at . You may want to check there for changes).
The purpose of this document is to provide you with a comprehensive list of URL pointers and programming tips on C++. Also, this document provides a Java-like String class, string tokenizer, memory functions and many other functions, which can be used in general C++ applications. C++ and Java is often used concurrently in many software projects. Programmers jump back and forth between C++ and Java will find this Java-like classes very helpful. Various examples are given which demonstrate the usage of this library and the Standard C++ Library.
This document is not a textbook on C++, and there are already several excellent on-line text books on the internet. Since C++ is being used for a long time there are very large number of C++ documents/articles/tutorials on Internet. If you are new to C++ and you never programmed in C++, then it is strongly suggested that you first either read an online C++ textbook given in chapter or you buy a C++ book from online bookstores such as or .
As someone said - Leave the C/C++ programming to system engineers who write operating system, device drivers and fast response real-time programming, you should use Java/PHP-scripting as speed of the computers in year 2005 will be several billion times faster than computers of year 2002!! Hardware is getting cheaper and faster.
C++ is one of the most powerful languages and will be used for a long time in the future in spite of emergence of Java or PHP-scripting. Programs which need real-time ultra fast response use C/C++. C++ runs extremely fast and is in fact 10 to 20 times FASTER than Java. Java is the "offspring" of C++. The only complaint against Java is - "Java is GOD DAMN SLOW" . Java byte-code is slower when running in a VM than the equivalent natively compiled code. Java runs faster with JIT (Just-In-Time) compiler, but it is still slower than C++. And optimized C/C++ program is about 3 to 4 times faster than Java compiled to native code with JIT compiler or ahead-of-time compiler!! Then, why do people use Java? Because it is pure object oriented and is easier to program in Java, as Java automates memory management, and programmers do not directly deal with memory allocations. This document attempts to automate the memory management in C++ to make it much more easy to use. The library given here will make C++ look like Java and will enable C++ to compete with the Java language.
Because of manual memory allocations, debugging the C++ programs consumes a major portion of time. This document will give you some better ideas and tips to reduce the debugging time.
When should you use C++ and when you should use Java/PHP?
Bottom line is, you use C++:
NOTE: There are lot of improvements in Java compilers (JIT and ahead-of-time). Java programs can be compiled with GNU GCJ , GCJ is a portable, optimizing, ahead-of-time compiler for the Java programming language. It can compile - Java source code directly to native machine code, Java source code to Java bytecode (class files), and Java bytecode to native machine code.
The Java native code compiler "gnu GCJ" is very rapidly maturing and in near future everybody will be programming in Java instead of C++. Special optimizers in gnu GCJ compiler can make Java programs as fast as C++ programs. The gnu GCJ compiler is 2-3 years away in becoming the de facto compiler on all platforms (initially on Linux and then on MS Windows).
GCJ resources:
Language choice is very difficult. There are too many parameters - people, people skills, cost, tools, politics (even national politics) and influence of business-people/commercial companies. The best language based on technical merits does not get selected simply due to political decisions!
See the language comparison chart of David Wheeler at . Ada got 93%, Java 72%, C++ 68% and C got 53%. C++ and Java are closer in points (only 4% difference). Development costs of Ada is half of C++ as per . Ada95 is available at -
The C++ compiler is lot more complex than a C compiler and C++ programs may run bit slower than C programs. The C compiler is very mature and seasoned.
On some system, you can use compiler options, to optimize the code generated.
Nowadays, C is primarily used for low level systems programming to develop operating systems, device drivers and applications which must perform fast.
Note: Using the String, StringBuffer, StringTokenizer and StringReader classes given in this howto, you can code in C++ which "exactly" looks like Java. Parts of this document tries to close the gap between C++ and Java, by imitating Java classes in C++. Java programmers who jump to and from C++ to Java will like this String class.
If you want to bypass the edit-compile-debug-compile cycle of C++ then see scripting languages like PHP which can be used for web development and for general purpose programming. Scripting languages like PHP and PERL enable rapid application development. PHP has some features of object-oriented programming. PHP is at .
1.3 Problems facing the current C++ compilers
Since C++ is a super-set of C, it has all the "bad" features of C. Manual allocation and deallocation of memory is tedious and error prone (see ).
In C programming - memory leaks, memory overflows are very common due to usage of features like -
Datatype char * and char[]The usage of char * and strcpy causes horrible memory problems due to "overflow", "fence past errors", "memory corruption", "step-on-others-toe" (hurting other variable's memory locations) or "memory leaks". The memory problems are extremely hard to debug and are very time consuming to fix and trouble-shoot. Memory problems bring down the productivity of programmers. This document helps increase the productivity of programmers via different methods addressed to solve the memory defects in C++. Memory related bugs are very tough to crack, and even experienced programmers take several days or weeks to debug memory related problems. Memory bugs may hide inside the code for several months and can cause unexpected program crashes. The memory bugs due to usage of char * and pointers in C/C++ is costing $2 billion every year in time lost due to debugging and downtime of programs. If you use char * and pointers in C++ then it is a very costly affair, especially if your program size is greater than 10,000 lines of code.
Hence, the following techniques are proposed to overcome the faults of C. Give preference in the following order -
To use "C char *", you would put all your C programs in a separate file and link to C++ programs using the linkage-specification statement extern "C" -
extern "C" {The extern "C" is a linkage specification and is a flag that everything within the enclosing block (brace-surrounded) uses C linkage, not C++ linkage.
The 'String class' utilizes the constructor and destructor features to automate memory management and provides access to functions like ltrim, substring, etc..
See also related in your C++ compiler. The string class is part of the Standard C++ Library library and provides many string manipulation functions.
Because the C++ 'string class' and 'String class' library provides many string manipulation functions, there is less need to use the character pointer approach to write your own string functions. Also, C++ programmers must be encouraged to use 'new', 'delete' operators instead of using 'malloc' or 'free'.
Both string classes do everything that char * or char [] do. One of the added benefits is that you do not have to worry about the memory problems and memory allocation at all.
The current C++ standard adopted by ISO and ANSI was first finalized in 1997, this means that not all compilers are up to pace yet, and not supporting all features - it is extremely important that you get a standard compliant C++ compiler.
Since MS Windows is quite popular for C++ development, the String class library given in this document works well and runs very well on all the versions of MS Windows i.e. MS Win XP/2000/NT/95/98/ME. The C++ compilers for MS Windows are:
In a GNU world, you will always be best off with GCC (GNU Compiler Collection), GCC is distributed with most Linux distributions, FreeBSD and most other UNIX clones. The GCC homepage is located at . The latest version of GCC (3.0) is one of the most standards compliant compilers out there.
The string class is the one of the most vital objects in programming, and string manipulations are most extensively used. There is a lot of varieties of string classes. Of course, you can build your own string class by simply inheriting from these string classes -
As mentioned above, you can build your own custom string class from the pre-built classes by single or multiple inheritance. In this section we will build a sample custom string class by using multiple inheritance, inheriting the standard C++ library string class and the String class presented in Appendix A.
Start by downloading the sample file 'string_multi.h' from .
That file is reproduced below:
// ******************************************************************
All the programs, examples are given in Appendix of this document. You can download as a single tar zip, the String class, libraries and example programs from
You may a have question of mis-trust of the String class software. To build confidence, there is a scientific method to verify the functionality of Al Dev's String class. In modern days, computer scientists use the CPU power instead of human brain power to verify and validate the software. Human brain is too slow and hence it is better to use the computer's power to test and validate software.
The program go here and click on 'Source code for C++'. (and also given in ) has regression test module which you can use to run the regression tests several millions of times automatically. After running the regression tests on the String class you can certify that the String class program is a ROCK SOLID and a BULLET-PROOF program.
I tested the String class with repeat cycle = 50000 and it ran and completed the program without crash. While it is running I did not notice any memory leak. On Linux, I used /usr/bin/gtop, UNIX top command, KDEStart->System->KDE System Guard and KDEStart->System->Process management to monitor the cpu and memory usage.
I recommend that you start the regression test with repeat cycle equal to 10 million or greater. The greater the repeat cycle number the greater will be your confidence!! Start the test and go to lunch (or go drink gharam chai - "chai peeke auvo") and come back to see the results!!
Take notice, this String class is not the same as the string class implemented in the Standard C++ Library. This special String class is a "home-made" String class, made to help Java programmers convert to C++. When you are more comfortable with C++, you should use the real string class provided in The Standard C++ Library.
To use String class, you should first refer to a sample program "example_String.cpp" given in and the String class which is given in .
The 'String class' is a complete replacement for char and char * datatype. You can use 'String class' just like char and get much more functionalities. You should link with the library 'libString.a' which you can build from the makefile given in and copy the library to /usr/lib or /lib directory where all the C++ libraries are located. To use the 'libString.a' compile your programs like -
g++ example.cpp -lString
The 'String class' provides these operators :-
The functions provided by String class have the same name as that of Java language's String class. The function names and the behaviour is exactly the same as that of Java's String class. StringBuffer class is also provided. This will facilitate portability of code between Java and C++ (you can cut and paste and do minimum changes to code). The code from Java's function body can be copied into C++ member function body and with very mininum changes the code will compile under C++. Another advantage is that developers coding in both Java and C++ do not need to remember two different syntax or function names.
For example to convert integer to string do -
String aa;Refer to for details about the String class function names. The same file String.h is reproduced here in next section.
Case 1: Simple rename
If you do not like the String class name then you can use "typedef" to rename the String class.
In all the files where you do include String.h, insert these lines:
// If you do not like the class name String, then you can rename using typedef
Case 2: Resolve conflict
If there is a conflict with another class-name having the same name, and you want to use both this class and conflicting class then you use this technique - in all the files where you do include String.h, insert these lines:
#define String String_somethingelse_which_I_want
C++ and Java are often used concurrently in many software projects. Programmers who jump back and forth between C++ and Java will find this string class very helpful.
In C++ (or any object oriented language), you just read the "class data-structure" (i.e. interface) to begin using that class. You just need to understand the interface and not the implementation of the interface. In case of String class, you just need to read and understand the String class in String.h file. You do not need to read the entire implementation (String.cpp) in order to use String class. The object oriented classes are real time saver and they very neatly hide the implementation.
(In object oriented Java language there is the equivalent called 'interface' , which hides the implementation details.)
Given below is the sample String.h file and see also
The String.h has more than 200 string manipulation functions but below only few functions are shown as sample.
// I compiled and tested this string class on Linux (Redhat 7.1) and
C++ and Java are often used concurrently in many software projects. Programmers jump back and forth between C++ and Java will find this stringbuffer class very helpful.
//
C++ and Java is often used concurrently in many software projects. Programmers jump back and forth between C++ and Java will find this stringtokenizer class very helpful.
//
While the previously mentioned String class (note the uppercase S), is a good thing for people coming from Java, then you should take notice of the "real" string class provided by The Standard C++ Library.
The string class was made to overcome one of the greatest pitfalls in C; character arrays. While character arrays are extremely fast, they have many bad sides. Character arrays are the cause of many bugs, and parsing character arrays is very time consuming.
The string class brings a good interface for parsing and handling strings,
and it's even STL compatible, so it can be used with all the general STL
algorithms. Actually you could say that a string is a
vector
Useful string references can be found at the following sites:
Creating a string is easy:
#includeThis code will create a string called "str', and put "Hello World!' into it. It is then being outputted to standard output by using cout.
(Note that I will skip the headers and the namespace from now on.)
Taking a substring of a string is also easy:
string str("Hello Universe!");This will put the first 6 characters into the string "start", and the rest into "end".
To get the size or length of a string, you would simply do this:
string str("How long is this string?");You can also use length() which works exactly the same.
Searching a string is much easier than using plain character arrays, the string class provides efficient member functions to search through the string. All member functions return string::size_type.
Member function | Purpose |
find() | find the first position of the specified substring |
find_first_of() | equal to find(), but finds the first position of any character specified |
find_last_of() | equal to find first of(), but finds the last position of any character specified |
find_first_not_of() | equal to find first of(), but returns the position of the first character not of those specified |
find_last_not_of() | equal to find last of(), but returns the last position of any characters not specified |
rfind() | equal to find(), but searches backwards |
|
A very common thing to do, is to search a string for contents. This can be done by using find()
string str("Hello, can you find Ben?");This code makes a case sensitive search for 'Ben' in the string, and puts the start position in the variable 'position' of type string::size_type. Note that the return value is not an int, but a string::size_type which is a special implementation defined integral value.
The member function find_first_of() needs a practical introduction, consider this:
string s = "C++ is an impressive language.";
By using find_first_of(), we can search the string for any character of the first argument, here we decide to search for a space or a dot.
Try compiling the program and check the output.
A very common operation with strings, is to tokenize it with a delimiter of your own choice. This way you can easily split the string up in smaller pieces, without fiddling with the find() methods too much. In C, you could use strtok() for character arrays, but no equal function exists for strings. This means you have to make your own. Here is a couple of suggestions, use what suits your best.
The advanced tokenizer:
void Tokenize(const string& str,The tokenizer can be used in this way:
#includeThe above code will use the Tokenize function, take the first argument str and split it up. And because we didn't supply a third parameter to the function, it will use the default delimiter " ", that is - a whitespace. All elements will be inserted into the vector tokens we created.
In the end we copy() the whole vector to standard out, just to see the contents of the vector on the screen.
Another approach is to let stringstreams do the work. streams in C++ have the special ability, that they read until a whitespace, meaning the following code works if you only want to split on spaces:
#include
And that's it! The stringstream will use the output operator (>>) and put a string into buf everytime a whitespace is met, buf is then used to push_back() into the vector. And afterwards our vector tokens will contain all the words in str.
C++ and Java are often used concurrently in many software projects. Programmers jump back and forth between C++ and Java will find this File class very helpful.
You would use the File class to manipulate the operating system files. This class is an imitation of Java's File class and will be very useful in C++ programming. Using this File class in C++ you can do if file exists() ?, if directory exists() ?, file length() and other functions.
Note that these classes have some great functionality not supported in the Standard C++ Library, but don't confuse them with fstreams(iostreams), which is the way you should perform many other operations on files.
In C, you use malloc(), free() and variants of malloc() to allocate and free memory, but these functions have their pitfalls. Therefore C++ introduced operators for handling memory, these operators are called new and delete. These operators allocates and frees memory from the heap (or sometimes called the free store) at runtime.
In C++, you should always use new and delete unless you're really forced to use malloc() and free(). But be aware that you cannot mix the two. You cannot malloc() memory, and then delete it afterwards, likewise you can't "new" memory, and then free it with free().
The delete and new operators in C++ are much better than the malloc and free functions of C. Consider using new and zap (delete function) instead of malloc and free as much as possible.
To make delete operators even more cleaner, make a Zap() inline function. Define a zap() function like this:
// Put an assert to check if x is NULL, this is to catchThe zap() function will delete the pointer and set it NULL. This will ensure that even if multiple zap()'s are called on the same deleted pointer then the program will not crash. Please see the function zap_example() in click on 'Source code of C++'.
// See zap_example() in example_String.cpp
There is nothing magical about this, it just saves repetetive code, saves typing time and makes programs more readable. The C++ programmers often forget to reset the deleted pointer to NULL, and this causes annoying problems causing core dumps and crashes. The zap() takes care of this automatically. Do not stick a typecast in the zap() function -- if something errors out on the above zap() function it likely has another error somewhere.
Also , my_realloc() and my_free() should be used instead of malloc(), realloc() and free(), as they are much cleaner and have additional checks. For an example, see the file "String.h" which is using the and my_free() functions.
WARNING : Do not use free() to free memory allocated with 'new' or 'delete' to free memory allocated with malloc. If you do, then results will be unpredictable.
See the zap examples in click on 'Source code of C++'.
Try to avoid using malloc and realloc as much as possible and use new and (delete). But sometimes you may need to use the C style memory allocations in C++. Use the functions my_malloc() , my_realloc() and my_free(). These functions do proper allocations and initialisations and try to prevent memory problems. Also these functions (in DEBUG mode) can keep track of memory allocated and print total memory usage before and after the program is run. This tells you if there are any memory leaks.
The my_malloc and my_realloc is defined as below. It allocates little more memory (SAFE_MEM = 5) and initializes the space and if it cannot allocate it exits the program. The 'call_check(), remove_ptr()' functions are active only when DEBUG_MEM is defined in makefile and are assigned to ((void)0) i.e. NULL for non-debug production release. They enable the total-memory used tracing.
void *local_my_malloc(size_t size, char fname[], int lineno)
An example on usage of my_malloc and my_free as below:
char *aa;
In C/C++ Garbage Collection is not a standard feature and hence allocating and freeing storage explicitly is difficult, complicated and is error-prone. The Garbage Collection (GC) is not part of the C++ standard because there are just so many ways how one could implement it; there are many GC techniques, and deciding to use a particular one would not be good for certain programs. Computer scientists had designed many GC algorithms, each one of them catering to a particular problem domain. There is no one single generic GC which will tackle all the problem domains. As a consequence, GC is not part of C++ standard, they just left it out. Still, you always have the choice of many freely available C++ libraries that do the job for you.
Visit these sites:
You must use const at every opportunity. The const is your most powerful anti-crash weapon. An additional benefit is that it makes your code self-documenting. For instance, look at this:
const char *add2strings(const char *sz1, const char *sz2);
Such a declaration guarantee's that no matter what wierd things go on within the function, it can't harm the application programmer's two strings sz1 and sz2. If any memory corruption occurs, it will be to variables within the function's scope. This, of course, greatly reduces side effect bugs.
Furthermore, the declaration of the return pointer as const means that the application programmer can't "reach inside" the function to corrupt its scope. For instance, if the return value is a static array of 40 characters, if the return wasn't static the application programmer could do this:
char *pchName = add2strings("James", "Bond 007");
Fortunately, because add2strings() returns a const pointer, you'll get a compiler error on this:
char *pchName = add2strings("Big galaxies", "Big stars");
Even if you declared pchName as a const char *, the moment you modified its contents with strcat() you'd get a compile error. The const keyword helps the programmer keep any errors localized, thus greatly reducing the likelihood of side-effect errors.
Forget you ever knew printf(). Use cout <<. Of course, scanf() was flirting with disaster even in the rough and ready C days. Use cin >>, or make your own input routines or classes. What about that wonderful sprintf()? Instead of this:
#include
Pointers are not required for general purpose programming. In modern languages like Java there is no support for pointers (Java internally uses pointers). Pointers make the programs messy and programs using pointers are very hard to read.
Avoid using pointers as much as possible and use references. Pointers are really a great pain. It is possible to write an application without using pointers. You should pointers only in those cases where references will not work.
A reference is an alias; when you create a reference, you initialize it with the name of another object, the target. From the moment on, the reference acts as an alternative name of the target, and anything you do to the reference is really done to the target.
Syntax of References: Declare a reference by writing the type, followed by the reference operator (&), followed by the reference name. References MUST be initialized at the time of creation. For example -
int weight;Do's of references -
Do not's of references -
Finding the exact source to a bug can be a troublesome process, however there is several techniques used for debugging:
Sites to help debugging:
To debug any C++ or C programs include the file and in your 'Makefile' define DEBUG_STR, DEBUG_PRT, DEBUG_MEM to turn on the traces from the debug.h functions. When you remove the '-DDEBUG_STR' etc.. then the debug function calls are set to ((void)0) i.e. NULL, hence it has no impact on final production release version of project. You can generously use the debug functions in your programs and it will not increase the size of production executable.
See the file for implementation of debug routines.
And see the file for a sample which uses debug.h and debug functions.
See the sample .
When programming C++, it is a good idea to used to an editor or an IDE. Most programmers have their own favourites, and it's a religious discussion on which is better.
You can choose to use an IDE (Integrated Development Environment), which is an application with embedded editor, compiler, documentation and more. And then there is the stand-alone editors, which some people like better.
The following IDE tools (Integrated Development Environment) are available for C++:
The problem with IDE's is many times their editors have a big lack of functionality. Therefore many people want a powerful editor alone, and then supply compiler next to it.
Of powerful editors, vim and emacs can be mentioned. They are both available for most platforms - and they support syntax highlighting and other things which will make you more efficient.
Other editors include UltraEdit(win32 only) and EditPlus(win32 only).
There are MORE THAN ONE MILLION online articles/textbooks/reference guides on C++ language. That is because C++ is used extensively for a very long period of time. You can find them using the Internet search engines like Google, Yahoo, Lycos, Excite etc..
Java books which will be useful for C++ programmers:
Visit the following C++ sites :-
Internet has vast amounts of documentation on C++. Visit the search engines like Google, Yahoo, Lycos, Infoseek, Excite. Type in the keywords 'C++ tutorials' 'C++ references' 'C++ books' . You can narrow down the search criteria by clicking on Advanced search and select search by exact phrase
There are many on-line tutorials available on internet. Type 'C++ tutorials' in the search engine.
Type 'C++ Reference' in the search engine.
Visit the following sites for Java like API for C++
Coding convention is very essential for readability and maintenance of programs. And it also greatly improves the productivity of the programmer. Coding convention is required for good coding discipline. The following is suggested - inside class definition:
In the sample code given below t stands for protected, v stands for private, m stands for member-variable and p stands for pointer.
class SomeFunMunchoVisit the C++ Coding Standards URLs
See also
The major disadvantage of C++ is that you must recompile and link the object files to create an executable anytime you make a small change. The compile/link/debug cycles take away a lot of time and is quite unproductive. Since modern CPU's and RAM are becoming extremely fast and cheap, it is sometimes better to spend more money on hardware and use scripting languages for development.
The scripting languages like PHP or PIKE eliminates the linking and re-compiling and will really speed up the development process.
As memory (RAM) prices are dropping and CPU speeds are increasing, scripting languages like PHP or PIKE will EXPLODE in popularity. PHP or PIKE will become most widely used scripting language as it is object oriented and it's syntax is very identical to that of C/C++.
Programming productivity will increase by five times by using the PHP or Pike C++ scripting language. And PHP or PIKE is very useful for 'proof of concept' and developing prototypes rapidly.
PHP is exploding in popularity for general purpose programming and for web development. PHP may become the most widely used scripting language in near future. PHP is at .
The Pike is at and at .
The Roxen Web server is completely written in Pike, which demonstrates how powerful Pike is. Pike runs much faster than Java for some operations and is quite efficient in using memory resources.
If you want commercial scripting language, get the 'Ch scripting' product from SoftIntegration corporation at .
The scripting language environment called Ch is a superset of C with high-level extensions, and salient features from C++ and other languages so that users can learn the language once and use it anywhere for almost any programming purposes. This C-compatible scripting language environment is also a middleware serving as crucial software infrastructure for running portable applications in heterogeneous platforms. The portable Ch code can be deployed safely over the internet or intranets to run anywhere ranging from supercomputers, workstations, PCs, Palm Pilots, PDA, to non-traditional computing devices such as CNC machines, robots, TVs, refrigerators, among others.
PHP is hypertext-preprocessor scripting language and is very rapidly evolving and adopting object oriented features. It has the "class" keyword through which it tries to implement object oriented scripting. May be in near future PHP will mature rapidly to become a robust scripting language for object oriented projects. In future it will tackle both the web applications and general purpose applications. Why have different scripting languages for web and general applications, instead just use PHP for both. PHP is at .
Templates is a feature in C++ which enables generic programming, with templates code-reuse becomes much easier.
Consider this simple example:
#include
Our printstring() takes a std::string as its first argument, therefore it can only print strings. Therefore, to print a character array, we would either overload the function or create a function with a new name.
This is bad, since the implementation of the function is now duplicated, maintainability becomes harder.
With templates, we can make this code re-usable, consider this function:
template
The compiler will automatically generate the code for whatever type we pass to the print function. This is the major advantage of templates. Java doesn't have templates but Java uses inheritance to achieve generic programming. For example in Java:
public static void printstring( Object o ) {
References:
Please visit the following sites for STL:
STL tutorials:
Main STL sites:
The STL offers the programmer a number of useful data structures and algorithms. It is made up by the following components.
I will be considering the use of the vector, list, set and map containers. To make use of these containers you have to be able to use iterators so I shall have something to say about STL iterators. Using the set and map containers can mean having to supply a simple function object to the instantiation so I shall also have something to say about function objects. I will only briefly mention the algorithms supplied by the STL. I will not mention adaptors at all.
I have taken liberty with some of the types of function arguments -- for example most of the integer arguments referred to in what follows actually have type size_type which is typedef'ed to an appropriate basic type depending on the allocation model being used. If you want to see the true signatures of the various functions discussed have a look at the Working Paper or the header files.
There are a number of utility classes supplied with the STL. The only one of importance to us is the pair class. This has the following definition:
template
and there is a convenient function make_pair with signature:
pair
as well as implementations of operator== and operator < . There is nothing
complicated about this template class and you should be able to use it
without further guidance. To use it #include the header file
To use the various bits of the STL you have to #include the appropriate header files. If your compiler is not standard compliant, this may differ, but a standard compliant compiler (like g++), would have these:
Note that headers in the Standard C++ Library are without a .h suffix. If you use an old or poor compiler, the above headers might fail, if then, you can try the version with the .h suffix, or better yet; get another compiler.
The container classes have many member functions that have the same names. These functions provide the same (or very similar) interface for each of the classes (though, of course, the implementations will be different). The following table lists the functions that we shall consider in more detail. A star opposite a function name indicates that the container type heading the column provides a member function of that name.
Operation | Purpose | vector | list | set | map | |
== | comparison | * | * | * | * | |
< | comparison | * | * | * | * | |
begin | iterator | * | * | * | * | |
end | iterator | * | * | * | * | |
size | no. of elements | * | * | * | * | |
empty | is container empty | * | * | * | * | |
front | first element | * | * | |||
back | last element | * | * | |||
[ ] | element access/modification | * | * | |||
insert | insert element(s) | * | * | * | * | |
push_back | insert new last element | * | * | |||
push_front | insert new first element | * | ||||
erase | remove element(s) | * | * | * | * | |
pop_back | remove last element | * | * | |||
pop_front | remove first element | * | ||||
|
If the following discussion leaves something unclear (and it will) you can always write a small test program to investigate how some function or feature behaves.
A vector is an array like container that improves on the C++ array type. In particular it is not necessary to know how big you want the vector to be when you declare it, you can add new elements to the end of a vector using the push_back function. (In fact the insert function allows you to insert new elements at any position of the vector, but this is a very inefficient operation -- if you need to do this often consider using a list instead).
Constructing Vectors
vector is a class template so that when declaring a vector object you have to state the type of the objects the vector is to contain. For example the following code fragment
vector
declares that v1 is a vector that holds integers, v2 a vector that holds strings and v3 holds objects of type FiniteAutomaton (presumably an user defined class type). These declarations do not say anything about how large the vectors are to be (implementations will use a default starting size) and you can grow them to as large as you require.
You can give an initial size to a vector by using a declaration like
vector
which says that v4 is to be vector of characters that initially has room for 26 characters. There is also a way to initialise a vector's elements. The declaration
vector
says that v5 is a vector of 100 floating point numbers each of which has been initialised to 1.0.
Checking Up on Your Vector
Once you have created a vector you can find out the current number of elements it contains by using the size function. This function takes no arguments and returns an integer (strictly a value of type size_type, but this gets converted to an integer) which says how many elements there are in the vector. What will be printed out by the following small program?
To check on whether your vector is empty or not you can use the empty function. This takes no arguments and returns a boolean value, true if the vector is empty, false if it is not empty. What will be printed out by the following small program (true prints as 1 and false prints as 0)?
Accessing Elements of a Vector
You can access a vector's elements using operator[]. Thus, if you wanted to print out all the elements in a vector you could use code like
vector
(which is very similar to what you might write for a built-in array).
You can also use operator[] to set the values of the elements of a vector.
vector
The function front gives access to the first element of the vector.
vector
You can also change the first element using front.
vector
The function back works the same as front but for the last element of the vector.
vector
Here is a simple example of the use of [].
Inserting and Erasing Vector Elements
Along with operator[] as described above there are a number of other ways to change or access the elements in a vector.
Note that insert and erase are expensive operations on vectors. If you use them a lot then you should consider using the list data structure for which they are more efficient.
In the above a vector v has been declared then initialised using push_back. Then some elements have been trimmed off it's end using pop_back. Next an ordinary integer array has been created and then some of its elements inserted into v using insert. Finally erase has been used to remove elements from v. The functions used above take arguments as follows.
Vector Iterators
The simple way to step through the elements of a vector v is as we have done above:
for (int i=0; i
Another way is to use iterators. An iterator can be thought of as a pointer into the container, incrementing the iterator allows you to step through the container. For container types other than vectors iterators are the only way to step through the container.
For a vector containing elements of type T:
vector
an iterator is declared as follows:
vector
Such iterators are constructed and returned by the functions begin() and end(). You can compare two iterators (of the same type) using == and !=, increment using ++ and dereference using *. [In fact vector iterators allow more operations on them - see next section for more information].
Here is an illustration of how to use iterators with vectors.
Note how *i can be used on the left-hand side of an assignment statement so as to update the element pointed at by i, and on the right-hand side to access the current value.
Comparing Vectors
You can compare two vectors using == and <. == will return true only if both vectors have the same number of elements and all elements are equal. The < functions performs a lexicographic comparison of the two vectors. This works by comparing the vectors element by element. Suppose we are comparing v1 and v2 (that is v1 < v2?). Set i=0. If v1[i] < v2[i] then return true, if v1[i] > v2[i] then return false, otherwise increment i (that is move on to the next element). If the end of v1 is reached before v2 return true, otherwise return false. Lexicographic order is also known as dictionary order. Some examples:
(1,2,3,4) < (5,6,7,8,9,10) is true.
The following code illustrates the third example above.
See the section
See the section
The set container type allows an user to store and retrieve elements directly rather than through an index into the container. The set container acts as a mathematical set in that it holds only distinct elements. However unlike a mathematical set, elements in a set container are held in (an user-supplied) order. In practice this is only a minor restriction on treating a set container as an implementation of the mathematical set abstract data type, and it allows for a much more efficient implementation than an unordered approach.
Constructing Sets
Two template arguments are required to construct a set container -- the type of the objects the set is to contain and a function object that can compare two elements of the given type, that is:
set
(The declaration set < T > s should also be possible -- it would use a default template argument less < T > as the second argument, but many C++ compilers (including g++) cannot as yet cope with default template arguments.)
For simple types T we can use the function object less < T > ( without having to worry about what a ``function object'' is), for example all the following are legal set declarations.
set
(Note that the space between the two final >'s in the template is required - otherwise the compiler will interpret >> as the right shift operator.) In each of these cases the function object makes use of the operator < as defined for the the underlying type (that is int, double, char and string).
The following code declares a set of integers, then adds some integers to the set using the insert method and then prints out the set members by iterating through the set. You will note that the set's contents are printed out in ascending order even though they were added in no particular order.
Note that 4 is added twice but only turns up once on the list of elements -- which is what one expects of a set.
What are Function Objects?
One of the nifty features of C++ is the ability to overload operators, so that one can have + mean whatever one likes for your newly designed class. One of the operators C++ allows you to overload is the function call operator () and this allows you to create classes whose instances can behave like functions in many ways. These are function objects.
Here is a simple example.
Function objects are used in a number of places in the STL. In particular they are used when declaring sets and maps.
The function object required for these purposes, let's suppose it is called comp, must satisfy the following requirements.
If for any particular objects x and y, both comp(x,y) and comp(y,x) are false then x and y are deemed to be equal.
This, in fact, is just the behaviour of the strictly-less-than relation (ie < ) on numbers. The function object less < T > used above is defined in terms of a < operator for the type T. It's definition can be thought of as follows.
template
(The actual definition uses references, has appropriate const annotations and inherits from a template class binary_function.)
This means that if the type T has operator < defined for it then you can use less < T > as the comparator when declaring sets of T. You might still want to use a special purpose comparator if the supplied < operator is not appropriate for your purposes. Here is another example. This defines a simple class with a definition of operator < and a function object that performs a different comparison. Note that the overloaded < and () operators should be given const annotations so that the functions work correctly with the STL.
The set s1 contains (1,a) and (2,a) as comparison is on the data member f1, so that (1,a) and (1,b) are deemed the same element. The set s2 contains (1,a) and (1,b) as comparison is on the data member f2, so that (1,a) and (2,a) are deemed the same element.
A Printing Utility
The way we have printed out the sets in the previous examples is a little awkward so the following header file containing a simple overloaded version of operator<< has been written. It works fine for small sets with simple element types.
The use here of << as an output routine for a set assumes that << has been defined for the set elements, and uses this to print a comma delimited list of the set elements wrapped in curly braces. It will be used without comment in the following examples.
How Many Elements?
You can determine if a set is empty or not by using the empty() method. You can find out how many elements there are in a set by using the size() method. These methods take no arguments, empty() returns true or false and size() returns an integer.
Checking the Equality of Sets.
Two sets may be checked for equality by using ==. This equality test works by testing in order the corresponding elements of each set for equality using T::operator==.
It is also possible to compare two sets using <. The comparison s1 < s2 is true if the set s1 is lexicographically less than the set s2, otherwise it is false.
Adding and Deleting Elements
The way to add elements to a set is to use the insert method (as we have done above). The way to delete elements from a set is to use the erase method.
For a set holding elements of type T these methods come in following forms:
The following example illustrates these various forms.
Finding Elements
We mention two member functions that can be used to test if an element is present in a set or not.
The use of find has been illustrated above. We could use count to write a simple template based set membership function. (This should also provide a version that takes a reference to the argument x.)
Set Theoretic Operations
The STL supplies as generic algorithms the set operations includes, union, intersection, difference and symmetric difference. To gain access to these functions you need to include algo.h. (In what follows iter stands for an appropriate iterator).
This checks to see if the set represented by the range [f2,l2] is included in the set [f1,l1]. It returns true if it is and false otherwise. So to check to see if one set is included in another you would use
includes(s1.begin(), s1.end(), s2.begin(), s2.end())
The includes function checks the truth of 3#3 ( that is of 4#4). This function assumes that the sets are ordered using the comparison operator <. If some other comparison operator has been used this needs to be passed to includes as an extra (function object) argument after the other arguments.
This forms the union of the sets represented by the ranges [f1,l1] and [f2,l2]. The argument result is an output iterator that points at the start of the set that is going to hold the union. The return value of the function is an output iterator that points at the end of the new set.
The fact that the result argument is an output iterator means that you cannot use set_union in the following, natural, fashion:
set
The reason is that begin() (also end()) when used with sets (or maps) returns a (constant) input iterator. This type of iterator allows you to access elements of the set for reading but not writing. (And this is a Good Thing since if you could assign to a dereferenced iterator (as in (*i)= ...) then you could destroy the underlying order of the set.)
The solution is to use an insert iterator based on the set type. This, basically, converts an assignment (*i)=value (which is illegal) into a (legal) insertion s.insert(i,value) (where s is the set object that the iterator i is pointing into). It is used as follows:
// Typedef for convenience.
Here is an example illustrating all these operations.
See the section
See the section
This section is written by and the document is located .
Introduction
Multi threaded programming is becoming ever more popular. This section presents a design for a C++ class that will encapsulate the threading mechanism. Certain aspects of thread programming, like mutexes and semaphores are not discussed here. Also, operating system calls to manipulate threads are shown in a generic form.
Brief Introduction To Threads
To understand threads one must think of several programs running at once. Imagine further that all these programs have access to the same set of global variables and function calls. Each of these programs would represent a thread of execution and is thus called a thread. The important differentiation is that each thread does not have to wait for any other thread to proceed. All the threads proceed simultaneously. To use a metaphor, they are like runners in a race, no runner waits for another runner. They all proceed at their own rate.
Why use threads you might ask. Well threads can often improve the performance of an application and they do not incur significant overhead to implement. They effectively give good bang for a buck. Imagine an image server program that must service requests for images. The program gets a request for an image from another program. It must then retrieve the image from a database and send it to the program that requested it. If the server were implemented in a single threaded approach, only one program could request at a time. When it was busy retrieving an image and sending it to a requestor, it could not service other requests. Of course one could still implement such a system without using threads. It would be a challenge though. Using threads, one can very naturally design a system to handle multiple requests. A simple approach would be to create a thread for each request received. The main thread would create this thread upon receipt of a request. The thread would then be responsible for the conversation with the client program from that point on. After retrieving the image, the thread would terminate itself. This would provide a smooth system that would continue to service requests even though it was busy servicing other requests at the same time.
Basic Approach
The create a thread, you must specify a function that will become the entry point for the thread. At the operating system level, this is a normal function. We have to do a few tricks to wrap a C++ class around it because the entry function cannot be a normal member function of a class. However, it can be a static member function of a class. This is what we will use as the entry point. There is a gotcha here though. Static member functions do not have access to the this pointer of a C++ object. They can only access static data. Fortunately, there is way to do it. Thread entry point functions take a void * as a parameter so that the caller can typecast any data and pass in to the thread. We will use this to pass this to the static function. The static function will then typecast the void * and use it to call a non static member function.
The Implementation
It should be mentioned that we are going to discuss a thread class with limited functionality. It is possible to do more with threads than this class will allow.
class Thread
It is important to understand that we are wrapping a C++ object around a thread. Each object will provide an interface to a single thread. The thread and the object are not the same. The object can exist without a thread. In this implementation, the thread does not actually exist until the Start function is called.
Notice that we store the user argument in the class. This is necessary because we need a place to store it temporarily until the thread is started. The operating system thread call allows us to pass an argument but we have used it to pass the this pointer. So we store the real user argument in the class itself and when the execute function is called it can get access to the argument.
Thread(); This is the constructor.
int Start(void * arg); This function provides the means to create the thread and start it going. The argument arg provides a way for user data to be passed into the thread. Start() creates the thread by calling the operating system thread creation function.
int Run(void * arg); This is a protected function that should never be tampered with.
static void * EntryPoint(void * pthis); This function serves as the entry point to the thread. It simply casts pthis to Thread * and
virtual void Setup(); This function is called after the thread has been created but before Execute() is called. If you override this function, remember to call the parent class Execute().
virtual void Execute(void *); You must override this function to provide your own functionality.
Using The Thread Class
To use the thread class, you derive a new class. You override the Execute() function where you provide your own functionality. You may override the Setup() function to do any start up duties before Execute is called. If you override Setup(), remember to call the parent class Setup().
Conclusion
This section presented an implementation of a thread class written in C++. Of course it is a simple approach but it provides a sound foundation upon which to build a more robust design.
If you have comments or suggestions, email to
Visit the following sites for C++ Utilities
Use the following memory debugging tools
Other Formats of this Document
This document is published in 14 different formats namely - DVI, Postscript, Latex, Adobe Acrobat PDF, LyX, GNU-info, HTML, RTF(Rich Text Format), Plain-text, Unix man pages, single HTML file, SGML (linuxdoc format), SGML (Docbook format), MS WinHelp format.
This howto document is located at -
You can also find this document at the following mirrors sites -
Single HTML file can be created with command (see man sgml2html) - sgml2html -split 0 xxxxhowto.sgml
PDF file can be generated from postscript file using either acrobat distill or Ghostscript. And postscript file is generated from DVI which in turn is generated from LaTex file. You can download distill software from . Given below is a sample session:
bash$ man sgml2latex
This document is written in linuxdoc SGML format. The Docbook SGML format supersedes the linuxdoc format and has lot more features than linuxdoc. The linuxdoc is very simple and is easy to use. To convert linuxdoc SGML file to Docbook SGML use the program ld2db.sh and some PERL scripts. The ld2db output is not 100% clean and you need to use the clean_ld2db.pl PERL script. You may need to manually correct few lines in the document.
You can convert the SGML howto document to Microsoft Windows Help file, first convert the sgml to html using:
bash$ sgml2html xxxxhowto.sgml (to generate html file)
In order to view the document in dvi format, use the xdvi program. The xdvi program is located in tetex-xdvi*.rpm package in Redhat Linux which can be located through ControlPanel | Applications | Publishing | TeX menu buttons. To read dvi document give the command -
xdvi -geometry 80x90 howto.dviAnd resize the window with mouse. To navigate use Arrow keys, Page Up, Page Down keys, also you can use 'f', 'd', 'u', 'c', 'l', 'r', 'p', 'n' letter keys to move up, down, center, next page, previous page etc. To turn off expert menu press 'x'.
man xdvi
You can read postscript file using the program 'gv' (ghostview) or 'ghostscript'. The ghostscript program is in ghostscript*.rpm package and gv program is in gv*.rpm package in Redhat Linux which can be located through ControlPanel | Applications | Graphics menu buttons. The gv program is much more user friendly than ghostscript. Also ghostscript and gv are available on other platforms like OS/2, Windows 95 and NT, you view this document even on those platforms.
To read postscript document give the command -
gv howto.ps
ghostscript howto.ps
You can read HTML format document using Netscape Navigator, Microsoft Internet explorer, Redhat Baron Web browser or any of the 10 other web browsers.
You can read the latex, LyX output using LyX a X-Windows front end to latex.
Copyright policy is GNU/GPL as per LDP (Linux Documentation project). LDP is a GNU/GPL project. Additional requests are that you retain the author's name, email address and this copyright notice on all the copies. If you make any changes or additions to this document then you please intimate all the authors of this document. Brand names mentioned in this document are property of their respective owners.
You can download all programs as a single tar.gz file from and give the following command to unpack
bash$ man tar
The students in Universities can debate the pros and cons of C++ and Java. Just for a debate sake, given below are some points discussing C++ versus Java: