OO COBOL: Comparison to C++

When I first started looking at OO COBOL, I was already familiar with the main features of C++. It was natural for me to look for analogous features in OO COBOL.

Here's what I have found so far, organized by C++ feature. I won't pretend that this comparison is either complete or completely accurate. As noted elsewhere, this discussion is based on IBM's implementation, mostly for mainframes. IBM has apparently implemented only a subset of the draft COBOL standard.

Object Model

IBM's implementation is based on SOM (System Object Model), a complex set of tools and built-in classes. It supports communication among objects written in different languages, following CORBA standards.

All classes inherit, directly or indirectly, from SOMObject. A class is itself an object instance of SOMClass. For special purposes you can define a metaclass derived from SOMClass.

Header Files

COBOL still has copybooks, of course. Unlike headers in C++, however, copybooks are not useful for representing class interfaces.

Since data members are not visible to the client code of a class (see below), the compiler doesn't need to know the size of the objects it uses. It merely needs to mangle the names of the methods so that the linker can look for the right routines.

However, the classes used by a program must be declared in the CONFIGURATION SECTION, in a special REPOSITORY paragraph.

IBM stores interface information in a special database called an IR (Interface Repository). The compiler may optionally consult the IR to enforce proper use of the classes described there. The IR plays roughly the same role as C++ header files, providing the equivalent of function prototypes for methods.

Friends, Templates, STL, Operator Overloading

Not available.

Inheritance

All inheritance is public, and should therefore be confined to "is-a" relationships among classes.

In C++ you would typically use private inheritance to represent a "has-a" or "is-implemented-as" relationship. Class Derived would inherit privately from Base. In OO COBOL, your best bet is to embed an object reference to a Base as a data member of Derived.

OO COBOL supports multiple inheritance. As with C++, there are rules for resolving conflicts among methods inherited from more than one parent class.

Data Members

A class definition declares data members in the WORKING-STORAGE section. Each object instance gets its own WORKING-STORAGE. There are no static data members.

All data members are private; i.e. they are accessible only to the methods of that class.

Member Functions

OO COBOL calls them "methods." Each method is defined as a mini-program within the PROCEDURE DIVISION of a class definition. It may have its own WORKING-STORAGE section, for data with persistent state. It may also have a LINKAGE section for passing parameters, and a LOCAL-STORAGE section for the equivalent of auto variables (their values do not persist from one call to the next).

All methods are virtual and public.

You don't CALL a method -- you INVOKE it. As with a CALL, you may specify a method with either a literal (for static linkage) or a data name (for dynamic linkage).

As with C++, the method invoked at run time depends on the type of the object referenced. If you invoke a method through a reference to a base class, but the reference refers to an object of a derived class, you'll invoke the method associated with the derived class, not the one associated with the base class.

Pure Virtual Functions and Abstract Base Classes

There's no way to declare a method without providing a definition of it. Hence you cannot define an abstract base class.

If you really need something like an abstract base class, you can build some clumsy checks to prevent the class from being instantiated. The constructor (see below) can interrogate the class for run-time type information, and abend if the object does not belong to a derived class. However there is no way to prevent instantiation at compile time.

References and Pointers

You can access an object only by invoking its methods, and you can invoke its methods only through an object reference. You cannot direct a pointer at an object, nor can you declare a static or auto instance of an object.

COBOL object references occupy a middle ground between pointers and references as we know them in C++.

Unlike a reference in C++, an object reference in OO COBOL can be NULL, or it may be reseated from one object to another, or to NULL. Unlike a pointer, you cannot dereference an object reference. You can use an object reference only to specify an object instance whose method you wish to invoke.

As with pointers, multiple object references may refer to the same instance.

Object references may be either typed or untyped. An untyped reference may refer to any object. A typed reference may refer only to an object of the designated class, or of a class derived from it.

Creation and Destruction

Every object instance is created dynamically via the somNew method, which corresponds to operator new in C++. somNew returns an object reference, by which you can invoke the object's methods.

Likewise the somFree method corresponds to operator delete.

You cannot allocate arrays of objects, so you don't need equivalents to operators new[] or delete[]. You can declare an array of object references and allocate each instance separately.

somNew and somFree are methods of SOMClass (a generic class of classes). Theoretically, if you define your own metaclass, you could override them with your own versions of somNew and somFree, just as you might override operators new and delete in C++. However, SOM is presumably not bound by COBOL's restrictions. It may not be possible to override these methods. I haven't tried it yet.

Constructors and Destructors

As noted above, all classes are derived from SOMObject. This ultimate base class has the methods somInit and somUninit, which correspond to a default constructor and a destructor, respectively. For SOMObject these methods do nothing, but you can override them for any class which needs them.

C++ calls a constructor whenever an object is created, and a destructor whenever the object is destroyed. Likewise, someNew invokes somInit whenever it allocates an object, and somFree invokes somUninit.

As with C++, OO COBOL invokes the constructor of a base class before invoking the constructor of the derived class. Likewise it invokes the destructor of the base class after invoking the destructor of the derived class. (I couldn't find anything in the manual that said so, but I did some experimenting.)

Like a default constructor in C++, somInit takes no parameters. There's no way to overload somInit with a parameterized constructor. The manual recommends that you define a metaclass with a parameterized method for creating an object. However, this approach offers no evident advantages over an ordinary subprogram.

Static Members

There are no static members. Data members occur separately for each object instance. Every method call pertains to a particular instance, although the WORKING-STORAGE of a method occurs once per class, not once per instance.

There are several ways to approximate static members:

However, there is no way to encapsulate such pseudo-static members properly. Even a metaclass has no special access to the internals of its instance classes. It can only use the same public methods that any other code can use.

Suppose, for example, you want to maintain a counter of all the instances of a class. You want to increment it whenever you allocate an instance, and decrement it whenever you deallocate. How do you enforce the proper maintenance of such a counter?

You could increment the counter in somInit, and decrement it in somUninit. However, there's no way to make the counter accessible to both methods without making it accessible to every routine in the load module.

You could bury the counter in a metaclass or a subprogram, and provide special methods or entry points for allocating and deallocating objects. However, you can't prevent the client code from calling somNew or somFree directly, bypassing the counter maintenance.

This inability to declare static members is a crippling weakness in IBM's implementation.


[home]Cobol Home [OOC]OO Cobol