Xavax C++ Library Class Index   FAQ   Overview

Answers to Frequently Asked Questions

Topics

  • General
    1. Why do some classes declare the copy constructor and assignment operator private?
    2. Why are the #include directives in the example code followed by filenames that are not enclosed in double quotes or angle brackets?
  • Containers
    1. What are the considerations for choosing containers that store objects by value versus containers that store objects by reference?
    2. When should the user provide a compare functor for containers?
  • General

    1. Why do some classes declare the copy constructor and assignment operator private?

      The copy constructor and assignment operator are declared private to prevent them from being used and to prevent the compiler from generating them automatically. This is done for classes where copying and assignment have no reasonable meaning, or could cause problems with resource management.

    2. Why are the #include directives in the example code followed by filenames that are not enclosed in double quotes or angle brackets?

      These are actually macros defined in Headers.h. The C preprocessor allows a #include directive to be followed by a filename enclosed in double quotes or angle brackets or a macro that evaluates to a filename enclosed in double quotes or angle brackets. The Xavax C++ Library exploits this feature as part of an efficient scheme for protecting against multiple inclusion of header files.

    Containers

    1. What are the considerations for choosing containers that store objects by value versus containers that store objects by reference?

      1. If objects of type T are to be stored by value, type T must provide a copy constructor.
      2. Containers that store objects of type T by value cannot store objects of a class derived from T since only the T "slice" of the objects are stored in and retrieved from the container. Containers that store objects of type T by reference can also store objects of any class deriving from T. For example, a container for type Shape could store a mixture of objects of type Circle, Triangle, and Square assuming these types are derived from Shape.
      3. Containers that store objects of type T by reference incur an additional overhead of sizeof(T*) bytes (typically 4 bytes); however, the same object can be stored in multiple containers without the overhead of creating multiple copies of the object as is the case when objects are stored by value.
    2. When should the user provide a compare functor for containers?

      There are two reasons to provide a compare functor. If type T does not implement operator== and operator<, the container template will not be able to generate a default compare functor; therefore, one must be provided by the user. The performance of the container can be improved by providing a compare functor that is more efficient than the default compare functor which consists of the following code.

      template<class T>
      int ClassName<T>::operator()(const T* p1, const T* p2)
      {
        int result;
        if ( *p1 == *p2 )
          result = 0;
        else if ( *p1 < *p2 )
          result = -1;
        else
          result = 1;
        return result;
      }
      
      This generic code is inefficient when the element type or the key embedded in the type is a native numerical type or a character string. Here are example compare functors for integers and character strings that are significantly more efficient than the default.
      int ClassName::operator()(const int* p1, const int* p2)
      {
        return *p1 - *p2;
      }
      int ClassName::operator()(const char** p1, const char** p2)
      {
        return strcmp(*p1, *p2);
      }
      

    Copyright © 2003 Xavax Inc. -- All Rights Reserved