|
INPRISE Online And ZD Journals Present:
A concrete data type (CDT) is a user-defined type that behaves just like a built-in type. In other words, a concrete data type can be created, deleted, assigned, copied, and passed as a parameter just like any C++ built-in type. This is a powerful feature that allows you to correctly make certain assumptions about how a specific class will behave. In this article, we'll learn how to build concrete data types, and, along the way, pick up on some subtleties of the C++ language itself. A simple CDTThe simplest CDT you can create is
Now, I admit that on the surface this class isn't very interesting. However,
looks can be deceiving. This class may look like nothing, but it is, in fact, a
complete and correct CDT. When the compiler is through with this class, it will
look something like this:
For the purists among us, I should mention that the compiler generates only
those methods that are actually called by the program. In other words, if you
never create an instance of class Nada, the compiler won't generate any code.
As another example, if your code doesn't call the copy constructor, the
compiler won't generate one.
A special note should also be made of the destructor. The compiler won't really
generate a destructor for this class. In fact, all of the following conditions
must be true for the compiler to generate a destructor for any class:
The constructorsThe "Constructing constructors" article explains the ins and outs of constructors, so we won't dwell on them too much here. However, it's worth pointing out that a CDT copy constructor must construct the instance in such a way that it remains valid even if the object being copied is deleted. The MyClass constructors are fine the way they are, so they don't need to be modified in our CDT conversion process.The destructorWe previously discovered that, in some cases, the compiler doesn't even create a constructor for a class. In these cases, how does the object clean up its member variables? When the compiler calls an object's destructor, the first thing it does is execute the code inside the destructor's code block. Then it automatically cleans up the member variables by destructing them--in the reverse order in which they were created. Next, it walks up the inheritance hierarchy, doing the same thing for each base class. If you don't declare a destructor, the compiler does the exact same thing, it just has no destructor code block to execute. Thus, you can rest safely, knowing that your member variables and base classes will be destructed, even if there is no explicit destructor. Symmetry is important in class design. In almost all cases, the destructor should perform the inverse operation of the constructor. Specifically, it should clean up any dynamic memory, close any open files, etc. So, in our attempt to convert MyClass into a CDT, we need to add the following code:
The assignment operatorThe assignment operator (also known as operator=) is often misunderstood. It's not the same as the copy constructor. Remember, the copy constructor actually constructs a brand new object instance, using another object instance to initialize itself. The assignment operator, however, assigns the value of one object instance to another, already existing instance. This is a subtle difference, but one which is very important.
As an example, consider a first attempt at writing a MyClass assignment
operator:
Our next attempt would look like this:
So, if the assignment operator of a class returns an object, or a constant
reference to an object, you can't write code like this. Now, some would argue
that you shouldn't write code like this in the first place, but that's beside
the point. The fact of the matter is that if you want your classes to be CDTs,
then you must return a reference to the assignee. The final version of the
assignment operator is as follows:
Derivation and CDTsIf you want your derived classes to behave as CDTs, then you must ensure that the big four are implemented correctly. The implementation of the derived class is identical to what we learned about any CDT. However, when you derive a class from a base class, there are several issues you must remember. First, there are some gotchas related to writing constructors for derived classes. Those can be found in the article, "Constructing constructors". Next, we must concern ourselves with the destructor. Since the compiler takes care of calling the base class destructor, we really have nothing special to worry about. However, as a note, any class that's intended to be used as a base class should have a virtual destructor. Note that if the base class has a virtual destructor, and the derived class doesn't declare a destructor, the compiler will generate a virtual destructor for the derived class. Finally, for the assignment operator, we must address a similar issue as we saw for the copy constructor. If the derived class doesn't declare an assignment operator, the base class assignment operator will be called, followed by a member-by-member assignment of the members in the derived class.
However, if the derived class does declare an assignment operator, the base
class assignment operator won't be called at all, unless the derived class
assignment operator specifically calls it. Thus, a derived assignment operator
would look like this:
ConclusionConcrete data types are very powerful, in that, once built, they can be used just like built-in types, without special consideration to how and when they can be allocated, and in what manner they can be used. Granted, there are some special considerations to be taken, but once the implementation is sound, the user of the classes needn't be concerned with any hidden subtleties. We encourage you to create concrete data types out of all your classes. Back to Top Back to 1999 Index of Articles Copyright © 1999, Ziff-Davis Inc. All rights reserved. ZD Journals and the ZD Journals logo are trademarks of Ziff-Davis Inc. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis is prohibited. Receive FREE Weekly C++ Builder Developer's Journal Tips in email. |