Object Identity and Instantiation

From RAD Studio
Jump to: navigation, search

Go Up to C++ and Delphi Class Models


In C++, an instance of a class is an actual object. That object can be directly manipulated, or it can be accessed indirectly through either a reference or a pointer to it.

For example, given a C++ class CPP_class with a constructor that takes no arguments, the following are all valid instance variables of that class:
 CPP_class by_value;// an object of type CPP_clas s 
 CPP_class& ref = by_value;// a reference to the object by_value, abov e 
 CPP_class* ptr =  new  CPP_class();// a pointer to an object of type CPP_clas s

By contrast, in Delphi a variable of type object always refers to the object indirectly. The memory for all objects is dynamically allocated. For example, given an Delphi class OP_class:

 ref: OP_class ; 
 ref := OP_class.Create ;
ref is a "reference" to an object of type OP_class.
Translated to C++Builder code, it would be:
 OP_class* ref =  new  OP_class;

Distinguishing C++ and Delphi references

Documentation frequently refers to an Delphi class instance variable as a reference, but describes its behavior as that of a pointer. This is because it has properties of both. An Delphi object reference is like a C++ pointer with the following exceptions:

  • An Delphi reference is implicitly dereferenced (in which case it acts more like a C++ reference).
  • An Delphi reference does not have pointer arithmetic as a defined operation.

When comparing an Delphi reference with a C++ reference, there are also similarities and differences. References in both languages are implicitly dereferenced, however,

  • An Delphi reference can be rebound, whereas a C++ reference cannot.
  • An Delphi reference can be nil, whereas a C++ reference must refer to a valid object.

Some of the design decisions underlying the FireMonkey and RTL frameworks are based upon the use of this type of instance variable. A pointer is the closest C++ language construct to an Delphi reference. Consequently, nearly all FireMonkey and RTL object identifiers are translated into C++ pointers in C++Builder.

Note: The Delphi var parameter type is a close match to a C++ reference.

Copying objects

Unlike C++, Delphi does not have built-in compiler support for making a copy of an object. This section describes the impact of this difference on assignment operators and copy constructors for Delphi style classes. Delphi style classes derive directly or indirectly from System::TObject.

Assignment operators

The Delphi assignment operator (:=) is not a class assignment operator (operator=()). The assignment operator copies the reference, not the object. In the following code, B and C both refer to the same object:

 B, C: TButton ; 
 B:= TButton.Create(ownerCtrl) ; 
 C:= B ;

This example translates to the following code in C++Builder:

 TButton *B = NULL ; 
 TButton *C = NULL ; 
 B = new TButton(ownerCtrl) ; 
 C = B;// makes a copy of the pointer, not the object

Delphi style classes in C++Builder follow the Delphi language rules for assignment operators. This means that, in the following code, assignments between dereferenced pointers are not valid because they attempt to copy the object, not the pointer:

 TRTLStyleClass *p =  new  TRTLStyleClass ; 
 TRTLStyleClass *q =  new  TRTLStyleClass ; 
 *p = *q;// not allowed for Delphi style class objects

Note: For Delphi style classes, it is still valid to use C++ syntax to bind a reference. For example, the following code is valid:

 TRTLStyleClass *ptr =  new  TRTLStyleClass ; 
 TRTLStyleClass &ref = *ptr;// OK for Delphi style classes

Although this is not the same as using an assignment operator, the syntax is similar enough that it is mentioned here for clarification and comparison.

Copy constructors

Delphi does not have built-in copy constructors. Consequently, Delphi style classes in C++Builder do not have built-in copy constructors. The following example code attempts to create a TButton pointer by using a copy constructor:

 TButton *B =  new  TButton(ownerCtrl) ; 
 TButton *C =  new  TButton(*B);// not allowed for Delphi style class object s

Do not write code that depends upon a built-in copy constructor for Delphi style classes. To create a copy of a Delphi style class object in C++Builder, you can write code for a member function that copies the object. Alternatively, descendants of the RTL TPersistent class can override the Assign method to copy data from one object to another. This is typically done, for example, in FMX graphics classes such as TBitmap and TIcon that contain resource images. Ultimately, the manner of copying an object can be determined by the programmer (component writer); but be aware that some of the copy methods used in standard C++ are not available for Delphi style classes.

Objects as function arguments

As discussed previously, instance variables in C++ and in Delphi are not identical. You should be aware of this when passing objects as arguments to functions. In C++, objects can be passed to functions either by value, by reference, or by pointer. In Delphi, when an object is passed by value to a function, remember that the object argument is already a reference to an object. So, it is, in fact, the reference that is passed by value, not the actual object. There is no Delphi equivalent to passing an actual object by value as in C++. Delphi style objects passed to functions follow the Delphi rules.

See Also