FAQs

C++ STL : What is the meaning of the 'Alloc' template parameter in 'vector'?

Q: What is the meaning of the 'Alloc' template parameter in 'vector'?
Q: How do I define my own allocator for use in STL containers?


A: The whole concept is very well explained in Gabriel and Andreas' article about Allocators.

The template parameter 'Alloc' specifies the type of allocator that the container should use to manage its memory. Every time the container needs a bit of memory, it will ask the allocator to retrieve it for him. The allocator usually just calls 'new' (and 'delete' when it has to free memory), but there can be more sophisticated strategies for allocators.

Usually, you are fine with the standard allocator provided by your STL. However, at times you may need to specify the allocation strategy explicitly. In theory, writing a custom allocator is not very difficult, but the task is complicated by the fact that the standard C++ design relies on template member functions which quite a few compilers don't support (e.g. Visual C++ 6).

A simple example for an allocator which never frees memory is this code (note that you need a recent compiler to get this to work):

#include <limits>
const size_t TEST_SIZE = 10000;
const double
TIME_MULTIPLIER = 100.0;
const
size_t MAX_SIZE = (TEST_SIZE + 1) * 12;
class
MemoryPool
{
unsigned char *m_data;
size_t m_top;
int
m_refcount;
public
:
MemoryPool()
{
m_data
= new unsigned char[MAX_SIZE];
m_top = 0;
m_refcount = 0;
}
~MemoryPool()
{
delete [] m_data;
}
void AddRef()
{
++m_refcount
;
}
void *alloc_mem(size_t n)
{
if ((MAX_SIZE - m_top) >= n) {
size_t old_top
= m_top;
m_top += n;
return
m_data + old_top;
} else {
return 0;
}
}
void Release()
{
if (--m_refcount == 0) {
delete this;
}
}
}
;
template
<class T>
class MyAlloc {
public:
// type definitions
typedef T value_type;
typedef
T* pointer;
typedef const
T* const_pointer;
typedef
T& reference;
typedef const
T& const_reference;
typedef
std::size_t size_type;
typedef
std::ptrdiff_t difference_type;
// rebind allocator to type U
template <class U >
struct rebind {
typedef MyAlloc< U > other;
};
// return address of values
pointer address (reference value) const {
return &value;
}
const_pointer address (const_reference
value) const {
return &value;
}
/* constructors and destructor
* - nothing to do because the allocator has no state
*/
MyAlloc() throw() {
m_pPool
= new MemoryPool;
m_pPool->AddRef();
}
MyAlloc(
const MyAlloc& src) throw() {
m_pPool
= src.m_pPool;
m_pPool->AddRef();
}
template <class U >
MyAlloc (
const MyAlloc< U > &src) throw() {
m_pPool
= src.m_pPool;
m_pPool->AddRef();
}
~MyAlloc()
throw() {
m_pPool->Release()
;
}
// return maximum number of elements that can be allocated
size_type max_size () const throw() {
return MAX_SIZE / sizeof(T);
}
// allocate but don't initialize num elements of type T
pointer allocate (size_type num, const void* = 0) {
// print message and allocate memory with global new
pointer ret = (pointer) m_pPool->alloc_mem(num * sizeof(T));
return
ret;
}
// initialize elements of allocated storage p with value value
void construct (pointer p, const T& value) {
// initialize memory with placement new
new((void*)p)T(value);
}
// destroy elements of initialized storage p
void destroy (pointer p) {
// destroy objects by calling their destructor
p->~T();
}
// deallocate storage p of deleted elements
void deallocate (pointer p, size_type num) {
// do not deallocate memory
}
MemoryPool *m_pPool
;
};
// return that all specializations of this allocator are interchangeable
template <class T1, class T2>
bool operator== (const MyAlloc<T1>&, const MyAlloc<T2>&) throw() {
return true;
}
template <class T1, class T2>
bool operator!= (const MyAlloc<T1>&, const MyAlloc<T2>&) throw() {
return false;
}

Note
: Most of the material in this article is taken from codeguru.com
Recommended Reading :

C++ STL : How to remove elements of a particular value from a container ?

Q: What is the best way to remove all elements of a particular value from a container?
A: Use the so-called 'remove/erase' idiom:

// taken from Item 32 of Scott Myers' Effective STL
vector<int> v;
v.erase(remove(v.begin(), v.end(), 99), v.end());

This is because of the simple fact that 'remove()' is a generic algorithm which takes iterators as its arguments. The iterators know nothing of their container; the STL was designed so as to grant the smallest possible amount of coupling. Thus, the iterators cannot call any container's 'erase()' or similar function.

'remove()' DOES return the container's new 'end()' (which just
happens to be the first element that was removed) and this value
can be used in the container's 'erase()' call.

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ : How to convert from std::string to CString?

Q: How to convert from std::string to CString?

A: This is simple... Use the CString constructor.

std::string strStdString ("Hello!");
// Using CString Constructor
CString strCString (strStdString.c_str ());

Let me add that CStringT can construct from both character or wide-character strings. i.e. It can convert from char* (i.e. LPSTR) or from wchar_t* (LPWSTR).

In other words, char-specialization (of CStringT) i.e. CStringA, wchar_t-specilization CStringW, and TCHAR-specialization CString can be constructed from either char or wide-character, null terminated (null-termination is very important here) string sources.

Q: How to convert from CString to std::string?

A: There are really many ways to do it.

But, the simplest one is just this -

CString strSomeCstring ("This is a CString Object");
// Use ANSI variant CStringA to convert to char*; construct from it -
std::string strStdString (CStringA (strSomeCstring));

CStringA is a template specialization of class CStringT for type char avaílable with Visual Studio 7.x and better.

Q: What are correlations between the CString Family and the Standard String Family?

A: If we were to draw a correlation between the CString Family and Standard String Classes, we would notice -

  1. CStringT as the equivalent of std::basic_string
  2. CStringA as the equivalent of std::string
  3. CStringW as the equivalent of std::wstring

However, the standard library itself doesn't contain a "CString" equivalent - one that can at best be -

std::basic_string <TCHAR>

This makes CString (VS 7.x +) "cool".

Q: The history of CString...

A: CString really wasn't always as likeable as it is today. If one were to compare the CString of Visual Studio 7.x and better with the class supplied by MSVC 6.0, one might not be wrong in judging the erstwhile version as relatively inflexible, and restrictive.

What made CString of yesterday "inflexible"?

1.Only for MFC-folks!

Yes... CString with MSVC 6.0 was notoriously connected to MFC Projects as if other project types didn't have any need for a TCHAR String Wrapper Class! One reason for it would be the linker error one would get for using this class in a non-MFC Project.

2. Need to use a CString? Convert to TCHAR!

CString is a string wrapper for TCHAR strings. In doing so, it came with a good number of helpful member methods. However, the implementation of this class in MSVC 6.0 was such that if a programmer needed to make use of the utility member methods, he would need to convert his string data type to TCHAR - back and forth.

This "restriction" automatically excluded programmers using ANSI strings (char*) in UNICODE builds from using this class, and ditto for those using UNICODE strings (WCHAR*) in non-UNICODE builds from using this class - as in both these cases, the strings in question aren't TCHAR strings - the type that CString wraps.

What makes CString of today "flexible" and actually more "likeable"?

1. Use it in any project type - even in a console application!

Yes... All the programmer needs to do is to include the following header -

#include <atlstr.h>

 

2. Don't change your String Type to suit CString! Choose the right CString instead!

With Visual Studio 7.x and better, CString is actually a specialization of template Class CStringT for type T as TCHAR.
Additionally, there exist two useful specializations of CStringT -

  • CStringA that specializes CStringT for type char, and
  • CStringW that specilizes CStringT for type wchar_t.
Hence, CString is actually CStringA for a non-UNICODE build and is a CStringW for a UNICODE build.

The existence of CStringA and CStringW gives the programmer, the flexibility to use the utility member methods supplied by CStringT even when their strings aren't of type - TCHAR.

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ String: What is the difference between '\n' and '\r\n'?

Q: What is the difference between '\n' and '\r\n'?

A:
Background
There are a few characters which can indicate a new line. The usual ones are these two:

  • '\n' or '0x0A' (10 in decimal) -> This character is called "Line Feed" (LF).
  • '\r' or '0x0D' (13 in decimal) -> This one is called "Carriage return" (CR).

Different Operating Systems handle newlines in a different way. Here is a short list of the most common ones:
  • DOS and Windows

    They expect a newline to be the combination of two characters, namely '\r\n' (or 13 followed by 10).

  • Unix (and hence Linux as well)

    Unix uses a single '\n' to indicate a new line.

  • Mac

    Macs use a single '\r'.

This difference gives rise to a number of problems. For example, a file created under Unix (so with newlines as a single LF) will not open correctly under Window's Notepad. Any Windows program that expects newlines to be CRLF will not work correctly with these files.

To unify things a bit, so that writing portable C/C++ programs is possible, file streams have both a "translated" and an "untranslated" mode. If you open a file in translated mode, the runtime library will convert a '\n' to the appropriate newline character(s). If the following program is compiled under Unix, the file will contain a single LF to indicate the newline. If it's compiled under windows, it will contain a CRLF.

#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp = fopen("testfile.txt", "w");
fprintf(fp, "Hello World\n");
fclose(fp);
return 0;
}

If you look at the generated file with a hex editor, you will see that the windows version has generated the following:

H e l l o W o r l d CR LF

0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x0D 0x0A

So file streams are handled in a transparent way, provided of course that you only handle files compatible with your operating system. But many times you have to pass multi-line strings directly to some system functions.

In practice
In Windows you have to pass multi-line strings with '\r\n', otherwise the system functions don't recognize them correctly as multi-line. This is true e.g. for setting the text of Edit controls, Labels, Windows etc. Also, when you read multi-line text from a file that initially contains '\r\n' in translated mode, the string in memory will contain only a single '\n'. See for example the documentation on MSDN about 'fread()':

Originally Posted by MSDN
The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. If the given stream is opened in text mode, carriage return

C++ String: What types of strings are there?

Q: What types of strings are there?

A:

  • 'char*' -> this is also called a C-style string, or an ANSI string.

  • 'wchar_t*' -> this is wide character string, i.e. an 'unsigned short*'

  • 'CString' -> this is a string wrapper class, which is part of the Microsoft Foundation Classes (MFC).

  • 'std::string' -> this is a Standard C++ Class wrapping a char string. It is part of the Standard Template Library, or STL.

  • 'std::wstring' -> this is a Standard C++ Class wrapping a wchar_t string. It is part of the Standard Template Library, or STL.

  • 'BSTR' -> this known as basic string or binary string, and is a pointer to a wide character string used by Automation data manipulation functions.

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ Design Pattern: What is a Singleton class?

Q: What is a singleton class?
A: A class whose number of instances that can be instantiated is limited to one is called a singleton class. Thus, at any given time only one instance can exist, no more.

Q: Can you give me an example, where it is used?
A: The singleton design pattern is used whenever the design requires only one instance of a class. Some examples:

  • Application classes. There should only be one application class. (Note: Please bear in mind, MFC class 'CWinApp' is not implemented as a singleton class)
  • Logger classes. For logging purposes of an application there is usually one logger instance required.

Q: How could a singleton class be implemented?
A: There are several ways of creating a singleton class. The most simple approach is shown below:
class CMySingleton
{
public:
static CMySingleton& Instance()
{
static CMySingleton singleton;
return singleton;
}

// Other non-static member functions
private:
CMySingleton() {}; // Private constructor
CMySingleton(const CMySingleton&); // Prevent copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent assignment
};


Q: Can I extend the singleton pattern to allow more than one instance?
A: The general purpose of the singleton design pattern is to limit the number of instances of a class to only one. However, the pattern can be extended by many ways to actually control the number of instances allowed. One way is shown below...

class CMyClass
{
private:
CMyClass() {} // Private Constructor

static int nCount; // Current number of instances
static int nMaxInstance; // Maximum number of instances

public:
~CMyClass(); // Public Destructor

static CMyClass* CreateInstance(); // Construct Indirectly

//Add whatever members you want
};

 

  • Here we declare our constructor/s as private, thus denying direct creation of the class.
  • A static function CreateInstance that creates the class indirectly for us.
  • Two static members, one holding the current number of instances, another one the maximum allowed.
  • Note: We have to declare at least one constructor (private - of course), else direct creation will be possible.
int CMyClass::nCount = 0;
int CMyClass::nMaxInstance = 1; // When maxInstance is 1, we have a pure singleton class
CMyClass::~CMyClass()
{
--nCount; // Decrement number of instances
}
CMyClass* CMyClass::CreateInstance()
{
CMyClass* ptr = NULL;
if(nMaxInstance > nCount)
{
ptr = new CMyClass;
++nCount; // Increment no of instances
}
return ptr;
}

 

  • Everytime an instance is created, the count is incremented, and when the object is deleted, the destructor is invoked, and the count is decremented.
  • Since, the objective is to limit the number of instances, we allow direct destruction of object.
  • As a special case, when 'maxInstance' is 1, we have a pure singleton class.


Now if you want to create an instance of the class:

CMyClass* pObj = CMyClass::CreateInstance();
if(pObj)
{
// Success
}
else
{
// Failed to create, probably because the maximum number of instances has already been created
}

Note, that the successfully created instance(s) need(s) to be released to ensure that no memory leak occurs:

delete pObj;

 

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ : Why do I get unresolved externals with my template code?

Q: I have the following code:

// In foo.h

 

template <typename T>
T foo(const T& t);

// end of foo.h
//------------------------------------------------

// In foo.cpp

template <typename T>
T foo(const T& t)
{
// function body
}

// end of foo.cpp
//------------------------------------------------

// In main.cpp

#include "foo.h"
int main()
{
int i = 1;
int j = foo(i);
}


But when I compile it, the linker tells me that "foo" (in whatever way the complier mangles foo<int>) is an unresolved external symbol.

A: There are actually two solutions to this problem - the "correct" one and the one that works. But before getting to that we need to understand why there is a problem.

The thing to understand about template code is that it's, well, a template. It's not real code. It's like when you have a letter template in your word processor: it's not a real letter until you fill in details like the person it's addressed to. In the example given, the compiler can't compile the definition of foo in "foo.cpp" because it doesn't know what T is. Until it knows that, it can't decide whether or not the operation you perform using T objects are valid or not. For example foo might call a specific member function of T called, say, bar(). But T is only a placeholder. Until you call foo with a specific type, how can the compiler know whether or not the code is valid?

So it comes down to this: templated functions (and classes) don't actually exist until you use them. And in order for the compiler to generate the real code for the function (or class), it has to have the complete definition of the template available at the point of use. If the full definition is not available, the compiler will assume that it's been defined somewhere else and just plant code for the call. And here's the problem with the example above: at the time foo is used (in main()), the compiler only has the declaration of foo available, so it assumes that foo<int> (because that's the instantiation that's wanted) is defined elsewhere. But the definition is in foo.cpp, and there is no use of foo<int> there, so the compiler won't bother generating it. And so we get to the situation that compiling main() plants a call to foo<int>, but compiling foo.cpp produces nothing. And that leads to an unresolved external reference.

The "correct" solution.

I call this correct, because it keeps the example code the way it is laid out. The standard defines a keyword export that is designed for just this situation. By defining foo in foo.cpp with export:

 

template <typename T>
export T foo(const T& t)
{
// definition
}

The definition becomes available to the compiler whilst it is comping main.cpp, and so it now generates the code for foo<int> and the external is resolved.

The solution that works.
Unfortunately, not many compilers support export, so the "correct" solution is more likely to produce a compilation error that it is to solve the problem. So the practical solution is define the function in the header file as an inline function:

// foo.h
template <typename T>
inline T foo(const T& t)
{
// definition
}

This way, because it's in the header file, the compiler can see it at the point of use and can generate the appropriate code and the external is resolved.

For those who think that's a bit ugly, and would like a solution that's half-way to the "correct" one (for that day when their compiler supports export), put the inine definition into a file called "foo.inl" and #include "foo.inl" at the end of the original foo.h. Then, when you get your new compiler, rename foo.inl to foo.cpp, change inline to export and remove the #include from foo.h.

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ : How to use class member functions as callbacks?

Q: How to use class member functions as callbacks?
A: The problem is that every callback function has its own prototype, which determines the parameters that gets passed from the operating system to it.
In C++ every member function has a hidden parameter - the so-called 'this' pointer which will be automatically passed to the function. C++ is able to associate a function with a particular instance of an object by means of the 'this' pointer. Member functions access member variables through the 'this' pointer...

class foo
{
public:
void func() { integer_ = 0; }

private:
int integer_;
};


If you compile this code it will be compiled as

class foo
{
public:
void func(foo* this) { this->integer_ = 0; }

private:
int integer_;
};

The operating system does not call callback functions through objects therefore it cannot handle the automatically added 'this' pointer... To get a member functions working as a callback routine you need to tell the compiler explicitly not to expect a 'this' pointer. To avoid the automatic 'this' pointer you have two possibilities:

  • Non-member functions
  • Static member functions

Non-member functions are not part of a class and therefore do not have a 'this' pointer. Static member functions do not receive a 'this' pointer either...thus, if you want to use a member function as a callback routine you need to declare it as 'static'...

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ : What are the differences between constant objects?

Q: What are the differences between constant objects?

A: To make any object constant, one uses the keyword 'const'. However, depending on the actual place you insert this keyword, it can have different meanings for the associated object:

  1. Reference to object -> Can change the referenced object
    foo instance;
    foo& reference_to_instance = instance;
  2. Reference to constant object -> Can not change the referenced object
    foo instance;
    const foo& constant_reference_to_instance = instance;
  3. Pointer to object -> Can change the adress it is pointing to as well as the object
    foo instance;
    foo* pointer_to_instance = &instance;
  4. Pointer to constant object -> Can change the adress it is pointing to but not the object
    foo instance;
    const foo* pointer_to_constant_instance = &instance;
  5. Constant pointer -> Can change the object but no the address it is pointing to
    foo instance;
    foo* const constant_pointer_to_instance = &instance;
  6. Constant pointer to constant object -> Can neither change the address nor the object
    foo instance;
    const foo* const constant_pointer_to_constant_instance = &instance;

Note: Most of the material in this article is taken from codeguru.com


Recommended Reading :

C++ : Why should I use '++i' instead of 'i++'?

Q: Someone told me that if I want to increment a variable and that's all, I should use ++x instead of x++. Is this true?
A: If incrementing is all that you want to do (you are not assigning the variable to something else), then yes this is a good practice, especially if you are using the increment operator on a class.

// Prefix operators are preferred in cases in the following common cases:
for (;checkstate(x);++x) dosomething(x);

++x;

For the standard data types there is usually no performance difference, but for classes there are! The reason is that (for most common implementations of) postfix operators retain a temporary copy of original variable and because the return value is returned by value, not by reference. The following code exemplifies this:

class MyClass
{
public:
MyClass& operator++() //Prefix increment operator (++x)
{
//Perform increment operation
return *this;
}

 

MyClass operator++(int) //Postfix increment operator (x++)
{
MyClass temp = *this;
//Perform increment operation
return temp;
}
};

Q: So what form of increment/decrement operator should I use for fundamental types when I can use either. For example:

double d = 3.14;
d--; // or should I use --d?
for (int i=0; i<10; i++) [COLOR=#008800]// or should I use ++i?

A: Use the pre-incement/decrement form (++i and --i)

Even though there is little impact for fundamental types, since we programmers are human, you will produce programming habits. And those habits will cary over to when we deal with classes instead, for example iterators.

There was an informal study done (sorry I forgot the source) on a number of people who say "I only use post-incrementing/decrementing for fundamental types." The results showed that they very frequently used the post-increment/decrementing operators for iterators and other classes leading to a great amount of wasted CPU cycles in the end code.

Note: Most of the material in this article is taken from codeguru.com

 


Recommended Reading :
Syndicate content



Cheap Flights - Mortgages - Loans - Loans