How to resolve "Delphi style classes have to be derived from Delphi style classes"?

Viewed 225

If I have a class defined as :

// foo.h
class Foo
{
public:
    virtual void GetFoo();
}

And I want a TForm to inherit from it, for example

class TFMainWindow : public TForm, public Foo
{
   ...
}

I get the error

[bcc32c Error] TFMainWindow.h(36): Delphi style classes have to be derived from Delphi style classes

How do I rsolve this issue?

1 Answers

TForm derives from TObject, which is a "Delphi-style class", ie it is implemented in Delphi pascal, not in C++. in Delphi, TObject is the root of all class object instances.

Delphi does not support multiple inheritance of classes, like C++ does. Only single inheritance. A Delphi class can have only 1 base class at most. But, it can implement multiple interfaces.

So, in C++Builder, when a C++ class has TObject as an ancestor, any other non-base ancestors MUST be interfaces only, which your Foo is not. An interface in this case is any class that has no data members, and only pure virtual methods and __property declarations are allowed.

If Foo::GetFoo() were a pure virtual method instead, then your code would work as expected, eg:

class Foo
{
public:
    virtual void GetFoo() = 0;
};

class TFMainWindow : public TForm, public Foo
{
    ...
public:
    void GetFoo();
    ...
};

This is simply a limitation of how C++ and Delphi interact with each other.

This is documented behavior:

C++ and Delphi Class Models: Inheritance and Interfaces

Unlike C++, the Delphi language does not support multiple inheritance. Any classes that you create that have RTL ancestors inherit this restriction. That is, you can not use multiple base classes for a Delphi style C++ class, even if the RTL class is not the immediate ancestor.

Using Interfaces Instead of Multiple Inheritance

For many of the situations where you would use multiple inheritance in C++, Delphi code makes use of interfaces instead. There is no C++ construct that maps directly to the Delphi concept of interface. An Delphi interface acts like a class with no implementation. That is, an interface is like a class where all the methods are pure virtual and there are no data members. While an Delphi class can have only a single parent class, it can support any number of interfaces. Delphi code can assign a class instance to variables of any of those interface types, just as it can assign the class instance to a variable of any ancestor class type. This allows polymorphic behavior for classes that share the same interface, even if they do not have a common ancestor.

In C++Builder, the compiler recognizes classes that have only pure virtual methods and no data members as corresponding to Delphi interfaces. Thus, when you create a Delphi style class, you are permitted to use multiple inheritance, but only if all of the base classes except the one that is a RTL or Delphi style class have no data members and only pure virtual methods.

Note: The interface classes do not need to be Delphi style classes; the only requirement is that they have no data members and only pure virtual methods.

Differences in object models between Delphi and C++ is also why C++ classes that are derived from TObject MUST be constructed in dynamic memory with new, even though C++ normally allows classes to be constructed in static/automatic memory without the use of new.

Related