Namespaces

August 12th, 2009 by carlos


A namespace is a feature that allows classes and functions to be created in a restricted scope, that is, accessible only using the name of the namespace as a qualifier for identifiers.

Namespaces exist to simplify the task of giving names to classes and functions. In C, all structs and functions are in the global namespace (unless they are made static). This means that it is very possible that a clash may happen between methods or structs defined in different libraries.

The most common method used to solve this problem in C and earlier versions of C++ was creating prefixes. For example, if a group developed a library called YZ, they would prefix all symbols define by this library with the YZ_ prefix. Therefore, this would prevent a clash with other symbols defined in different libraries.

Modern languages avoid this problem by making all code part of a module, where definitions of symbols are maintained. Symbols can only be referenced by importing a module, according to the rules of the language. For example, Java has packages, C# has assemblies, and Python has modules.

In C++, namespaces are not required, but are strongly encouraged for new development. Using namespaces means that there are less opportunities for clashes with software that was written by other people.


Examples

Here is an example of how to define a namespace called “Example”:

namespace Example {
  class A {
   void test();
  }
}

Code can be added to a namespace by simply using the namespace block as show above:

namespace Example {
void A::test() { std::cout << " a test \n"; }
}

To use a class defined in a namespace, you can refer to the fully qualified name (namespace + class name):

void test2() {
   Example::A a = new Example::A();
}

The second possibility is employing the using clause:

using namespace Example;
void test3() {
   A a = new A();
}

Exceptions Inside Exceptions

August 6th, 2009 by carlos


One of the risks that we incur when working with exceptions, is having to control what is happening when the exception is received in the catch block.

An exception is thrown, as we have seen in the article about exceptions when the keyword throw is used. Then, a new object of the type determining the exception is created. For example, we can create a new exception in the following way:

void Obj::AMethod() {
   // ....
   if (error)
      throw new MyCustomException("something bad happened");
}

An exception is catch by a catch block that can be added to any code surrounding the place where the exception was thrown. Surrounding here means not only the code that directly throws the exception, but also any code that called the method where the exception is being thrown.

Here is an example:

void Obj::Example() {
   try {
   // ...
      this->AMethod();
   } catch (MyCustomException &e) {
      // process the exception here
   }
}

The main problem we are concerned about here is what happens between the moment the exception is thrown and the moment the program can restart on the catch block.

The main problem with catching exceptions, is that we need to make sure that no additional exceptions will be thrown during the process of destroying objects. For example, if the code above has an object with a destructor that throws another exception, then we have a problem.

Notice that, when throwing an exception, C++ maintains a context, which determines what destructor will be called in response to the exception. The fact is that all objects created in the context between the place where an exception was thrown until the catch block need to be destroyed.

If we send an exception during the destruction process, then C++ can become confused about what objects needs to be destroyed as a result. It is as if there were are double queue of objects that need to have their destructor called.

In such a situation, C++ won’t know what to do, and the program will simply stop working correctly and crash.

To avoid problems like this, the main suggestion is that we should avoid throwing exceptions on a destructor. We never know in what context a destructor will be called, so it is better to avoid throwing exception on any destructor.

Exceptions

July 27th, 2009 by carlos


An exception is an indication that something unexpected occurred in a C program. The mechanism used by C to handle exceptions is using the try/catch pair of keywords.

An exception is represented in C++ by an object that encodes the condition that caused the exceptional event. One can use this object by means of the throw keyword.

The try/catch mechanism allows one to create a context in which we can protect against exceptions. For example

class MyException { /* ... */ }
int i = 0;
try {
  i = performCalculation();
}
catch (MyException &e) {
   cout << "an exception occurred\n";
}

Observations: * note that in the catch clause, the exception is taken by reference. This is useful to avoid the need of copying the object.

Once you detect an exceptional condition, the exception can be throw using code like this:

if (conditionHappened)
  throw new MyException();