Object Identity and Instantiation
Go Up to C++ and Object Pascal 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.
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 Object Pascal a variable of type object always refers to the object indirectly. The memory for all objects is dynamically allocated. For example, given an Object Pascal class OP_class:
ref: OP_class ; ref := OP_class.Create ;
OP_class* ref = new OP_class;
Distinguishing C++ and Object Pascal references
Documentation frequently refers to an Object Pascal class instance variable as a reference, but describes its behavior as that of a pointer. This is because it has properties of both. An Object Pascal object reference is like a C++ pointer with the following exceptions:
- An Object Pascal reference is implicitly dereferenced (in which case it acts more like a C++ reference).
- An Object Pascal reference does not have pointer arithmetic as a defined operation.
When comparing an Object Pascal reference with a C++ reference, there are also similarities and differences. References in both languages are implicitly dereferenced, however,
- An Object Pascal reference can be rebound, whereas a C++ reference cannot.
- An Object Pascal 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 Object Pascal reference. Consequently, nearly all FireMonkey and RTL object identifiers are translated into C++ pointers in Appmethod C++.
Note: The Object Pascal var parameter type is a close match to a C++ reference.
Unlike C++, Object Pascal 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 Object Pascal style classes. Object Pascal style classes derive directly or indirectly from System::TObject.
The Object Pascal 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 Appmethod C++:
TButton *B = NULL ; TButton *C = NULL ; B = new TButton(ownerCtrl) ; C = B;// makes a copy of the pointer, not the object
Object Pascal style classes in Appmethod C++ follow the Object Pascal 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 Object Pascal style class objects
Note: For Object Pascal 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 Object Pascal 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.
Object Pascal does not have built-in copy constructors. Consequently, Object Pascal style classes in Appmethod C++ 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 Object Pascal style class object s
Do not write code that depends upon a built-in copy constructor for Object Pascal style classes. To create a copy of a Object Pascal style class object in Appmethod C++, 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 Object Pascal style classes.
Objects as function arguments
As discussed previously, instance variables in C++ and in Object Pascal 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 Object Pascal, 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 Object Pascal equivalent to passing an actual object by value as in C++. Object Pascal style objects passed to functions follow the Object Pascal rules.