Class Access Levels

April 20th, 2009 by carlos


C++ provides three access levels for members of a class. Both member variables and member functions can be tagged as public, private, or protected, depending on the intended use of the member in the class.

A public data member of member function is one that can be accessed by any user of the class, independent of where the user is located. Thus, member functions that are declared public can be accessed anywhere, and represent the public interface of a C++ class.

Public member variables are also allowed to be viewed anywhere in the program. However, allowing this to happen is usually not a good idea, since it would inibit future changes in the representation of the data stored in a class. Unless you really need to do this for some reason (for example, compatibility with C code), you should avoid the creation of public member variables in a C++ class.

Private member variables, on the other hand, are not visible outside the class where they are declared. This is the preferred way of declaring member variables in C++, since it guarantees that the usage of data is limited to the class itself.

Like private member variables, private member functions are also useful in C++ programs. Such member functions are used in the implementation of the class, and are not accessible to users of the class. Every member function that is not part of the interface should be made private (or at least protected).

In fact, C++ defines private access as the default level of access for class member. That is, if you don’t specify anything as the access level, then the member will be considered private.

The other level of accessibility is the protected level. A member function or member variable is protected if it is accessible only inside a class or by the classes that derive from it. Therefore, only classes that inherit from the class where the member is contained can have access to the function or variable.

Protected members of a class are useful to provide functionality for derived classes. However, they should be used with care. One of the main problems, is that classes that expose too many details to derived classes may have difficulties when changing their internal representation, since an unspecified number of derivate classes may be using the protected information.


Example

Here is an example of the access level described above. Note that the method Director::getInfo() incorrectly tries to access getAge, since it is a private method.

class Employee {
  // private member variable
  int age;
  // private member function
  int getAge() { return age; }
public:
  // public member variable (don't do this!)
  std::string name;
  std::string getName() { return name; }
protected:
  // these members are visible only inside Employee
  // and derived classes
  std::string telephone;
  std::string getTelephone() { return telephone; }

};

// A derived class
class Director : public Employee {
   public:
   void getInfo();
};

void Director::getInfo() {
   // this works - protected
   cout << getTelephone() << "\n";
   // this doesn't work - private to Employee
   cout << getAge() << "\n";
}

Important

Don’t forget to add the public: tag before public members. Remember that the default access level in C++ is private.

Using the assert macro in C++

April 9th, 2009 by carlos


Writing good software is a difficult proposition. It is sometimes easy to write sub-par software, with a high number of defects and poor maintainability, but to make sure that software has good quality and is easy to modify one needs to take care of many issues.

One of the necessary factors in creating good software is guaranteeing that it satisfy its requirements. One of the simplest methods for doing this is using the assert facility provided by the standard C++ library.

Using Assert

Assert is a mechanism that allows a program to stop an error in its tracks whenever it is detected.  Assert is implemented in C++ as a macro, where the first argument is a boolean expression. This expression is evaluated, and its result is always expected to be true.

For example, the following is a typical use of assert:

void test(int value) {
  assert(value > 0);
  // normal processing

In the example above, the assert tests if the argument passed to function test is greater than zero. If this is true, processing continues as normal. However, in the case that value is negative or zero, the assertion fails and the program stops immediately.

The assert macro is defined in assert.h, a header file that is  also used by the C compiler — so you can use assert on C or C++.

Using assert in a testing environment is a first step towards guaranteeing that we have the correct values before our algorithm starts. It is an easy method and has been effectly used in this way by many experienced programmers. 

Disadvantages of Assert

Although there are many advantages on using assert, one also needs to be aware of the problems in its use. First, asserts are not a substitute to using exceptions. When there is a possibility of recovery from an error, then the exception mechanism should be used. This way, the programmer has control over how a failure in the code must be handled. With an assert, on the other hand, the whole program stops.

In general, asserts should not be used on production code. The reason is that asserts are not graceful, they just stablish that an error ocurred, and stop the program. This is certainly not the behavior required in production, where the appropriate steps need to be taken to guarantee that user data is preserved.

Conclusion

Asserts are a powerful mechanism provided by C++ to guarantee that certain conditions are present on a specific function. If the expression given as input is not true, then the assert will automatically call the attention of the developer.

Asserts should be used sparingly, however, and not at all in production. Thankfully, all implementations of assert have a mechanism to disable it in production code. Check the documentation of NDEBUG in your favorite compiler for the details.

Some features of the C++0x standard

April 7th, 2009 by carlos


C++ is growing and changing. As has been the case for the last 20 years, C++ has been developing new features as a response to the changes in computing.
The latest trend of changes in the C++ language is due to the update of the Standard.

A work that has taken many years, the new standard that is by now only known as C++0x (where x will be probably 9) will add many features that will change the way we develop software in C++.

Improved Templates

Templates are the feature in C++ that was used to create reusable containers for any object. Thanks to templates we have now a powerful standard library, with  containers (such as vectors, lists, trees, and strings), and algorithms that operate on these containers.

On the new standard, templates will be improved by providing information on the types that can be used to specialize a template. This is a form of type inference that will make templates much more useful (and with better error codes).

Another nice feature is the addition of auto detection of variable types. Since the type system of C++ is very sophisticated, it makes sense to have a feature in the language to allow types to be automatically detected. The language will use the keyword auto to determine that a variable has the same type as the right hand side on an assignment. So, something as

auto a = new MyObject(); 

is sufficient to create a variable of the type MyObject. Notice that we just need to write MyObject once (while nowadays we needed to repeat the type name before the variable name).

Other Features

The new standard has also several provisions that will improve programming in many ways. Examples include new types of constants, improved initialization of objects, among others. I plan to write about some of these features in the future — stay tuned.

Related Articles

Basecamp