Top 20 C++ Tips (Part 4) – Object-oriented Design

Although C++ supports several useful programming paradigms such as procedural programming, functional programming, and generic programming, object-oriented programming is unquestionably the most widely used and important paradigm. The following two tips provide guidelines for better object-oriented design and implementation. First, I will explain the importance of virtual destructors in class hierarchies. The next tip in this category shows how to deal with nested classes that are declared as friends of the enclosing class.

Tip 12: Why Inheriting from a Class That Has No Virtual Destructor is Dangerous
Classes with a non-virtual destructor aren’t meant to serve as base classes (such classes are usually known as “concrete classes”). std::string, std::complex, and std::vector are concrete classes. Why is inheriting from such classes not recommended? When you use public inheritance, you create an is-a relationship between the base class and its derived classes. Consequently, pointers and references to base can actually point to a derived object. Because the destructor isn’t virtual, C++ will not call the entire destructor chain when you delete such an object. For example:

class A
{
public:
  ~A() // non virtual
  {
  // ...
  }
};

class B: public A /* bad; A has a non virtual dtor*/
{
public:
  ~B()
  {
  // ...
  }
};

int main()
{
 A * p = new B; /*seemingly OK*/
 delete p; /*trouble, B's dtor not called*/
}

The result of failing to invoke an object’s destructor is undefined. Therefore, you shouldn’t use publicly inherit from such classes. In particular, don’t derive from STL containers and std::string, as tempting as it may seem.

Tip 13: Declaring Nested Classes as Friends of Their Enclosing Class
When you declare a nested class as a friend of its containing class, place the friend declaration after the declaration of the nested class, not before it:

class A
{
private:
 int i;
public:
 class B /*nested class declared first*/
 {
  public:
  B(A & a) { a.i=0;}; /*access A's private member*/
 };
 friend class B;/*friend declaration at the right place*/
};

If you place the friend declaration before the nested class’s declaration, the compiler will discard the declaration since the friend class hasn’t been seen yet.

The Top 20 C++ Tips of All Time – Introduction

Part 1 – Guidelines for Better Coding Style

Part 2 – Memory Management

Part 3 – Performance Enhancements

Part 4 – Object-oriented Design

Part 5 – STL and Generic Programming

Related Posts

 

Article by Tuan

I am the administrator of Tek3D Weblog, which was created in December 2008. I write about anything related to technology and science. Wordpress blogging tips and technology news are my favourite topics. Subscribe to the RSS or Twitter to receive my blog's latest updates.

Tuan has written 488 awesome articles for us at Tek3D Weblog



dofollow No Responses

Leave a Reply

CommentLuv Enabled