Dynamic Functions

From RAD Studio
Jump to: navigation, search

Go Up to Virtual Functions Index

dynamic functions are allowed for classes derived from System.TObject. Dynamic functions are similar to virtual functions except for the way they are stored in the virtual tables.

  • Virtual functions occupy a slot in the virtual table in the object they are defined in, and in the virtual table of every descendant of that object.
  • Dynamic functions occupy a slot in every object that defines them, but not in any descendants.

That is, dynamic functions are virtual functions stored in sparse virtual tables. If you call a dynamic function, and that function is not defined in your object, the virtual tables of its ancestors are searched until the function is found.

Therefore, dynamic functions reduce the size of your virtual tables at the expense of a delay at run time to look up the address of the functions.

Because dynamic functions are available only in classes derived from TObject, you get an error if you use them in a regular class. For example:

class dynfunc {
  int __declspec(dynamic) bar() { return 5; }
 };

gives the syntax error, "Error: Storage class 'dynamic' is not allowed here."

But the following code compiles:

#include <System.hpp>
#include <stdio.h>
class __declspec(delphiclass) func1 : public TObject {
 public:
  func1() {}
  int virtual virtbar() { return 5; }
  int __declspec(dynamic) dynbar() { return 5; }
 };
class __declspec(delphiclass) func2 : public func1 {
 public:
  func2() {}
  };
class __declspec(delphiclass) func3 : public func2 {
 public:
  func3() {}
  int virtbar() { return 10; }
  int __declspec(dynamic) dynbar() { return 10; }
 };
int main()
 { 
  func3 * Func3 = new func3; func1 * Func1 = Func3; 
  printf("func3->dynbar: %d\n", Func3->dynbar()); 
  printf("func3->virtbar: %d\n", Func3->virtbar()); 
  printf("func1->dynbar: %d\n", Func1->dynbar()); 
  printf("func1->virtbar: %d\n", Func1->virtbar()); 
  delete Func3; func2 * Func2 = new func2; 
  printf("func2->dynbar: %d\n", Func2->dynbar()); 
  printf("func2->virtbar: %d\n", Func2->virtbar()); 
  delete Func2; return 0; 
 }

Dynamic attribute is inherited

In general, dynamic functions are just like virtual functions, and the dynamic attribute is automatically inherited.

However, if a derived type declares a method with the same signature as a dynamic method in a base type, the method will be assigned the same dynamic id, but the method in the derived type must specify __declspec(dynamic). Otherwise the compiler generates the error: [BCC32 Error] wibwob2.cpp(21): E2113 Virtual function 'func3::dynbar()' conflicts with base class 'func1'

You can verify this by running the above example. When you generate assembly output with "bcc32 -S" you can examine the virtual tables of func1, func2, and func3, and see how func2 has NO entry for dynbar, but it does have an entry for virtbar. Still, you can call dynbar in the func2 object:

Output:

func3->dynbar: 10
func3->virtbar: 10
func1->dynbar: 10
func1->virtbar: 10
func2->dynbar: 5
func2->virtbar: 5

Dynamic functions cannot be made virtual, and vice-versa

You cannot redeclare a virtual function to be dynamic; likewise, you cannot redeclare a dynamic function to be virtual. The following example gives errors:

 #include <vcl.h>;
 #include <stdio.h>;
 class __declspec(delphiclass) foo1 : public TObject {
  public:
   foo1() {}
   int virtual virtbar() { return 5; }
   int __declspec(dynamic) dynbar() { return 5; }
  };

 class __declspec(delphiclass) foo2 : public foo1 {
  public:
   foo2() {}
   int __declspec(dynamic) virtbar() { return 10; }
   int virtual dynbar() { return 10; }
  };

 Error : Cannot override a virtual with a dynamic function

 Error : Cannot override a dynamic with a virtual function

See Also