Reputation: 78934
A common practice in C to implement "Object Oriented" is using an array of function pointers. This seems to be similar to the C++ vtable and in essence the C++ virtual functions mechanism is just syntactic sugar around an array of function pointers.
But the C mechanism has an additional feature which is missing in C++. A function pointer can be NULL and the caller can check if the function is NULL to see if an object implements a certain method. In C++ however a method cannot be NULL and a class cannot "not implement" a method.
What is the closest way of mimicking this behavior in C++?
Upvotes: 2
Views: 879
Reputation: 147
It sounds like you are trying to do compatibility checks at run time. There are a couple ways to structure your class hierarchy you could use a fat interface where your base class implements all the possible derived function and have them throw errors upon execution if a derived class doesn't override the the implementation. Which is kind of what you are doing in C.
The other and more desirable way to accomplish this is through capability classes and using multiple inheritance to mix in capabilities.
Look at pages 9-11 to get more details on designing and implementing this.
http://www.umich.edu/~eecs381/lecture/IdiomsDesPattsStructural.pdf
Upvotes: 0
Reputation: 437386
The closest way is by designing a class hierarchy to accurately model what the C-style vtables implement.
Two arrays of function pointers (vtables) that have a different number of elements are modelling two separate classes. This is quite apparent, but it should also be apparent that vtables with different number of non-null elements also model separate classes even if the sizes of the arrays are the same.
For example, assume we have a vtable and two objects that aggregate it like this:
VTABLE OBJECT A OBJECT B
STRUCTURE
+-------------+ +-------------+ +-------------+
| pfnCreate | | 0x..... | | 0x..... |
+-------------+ +-------------+ +-------------+
| pfnUpdate | | 0x..... | | NULL |
+-------------+ +-------------+ +-------------+
| pfnDelete | | 0x..... | | 0x..... |
+-------------+ +-------------+ +-------------+
The two objects are not of the same class (at least using the C++ definition of a class), so it's not surprising that you cannot model the state of affairs using just one class. Translated to C++, this would look like
class Something {
public:
void Create();
void Delete();
};
class UpdatableSomething : public Something {
public:
void Update();
}
where B is a Something
and A is an UpdatableSomething
.
Upvotes: 1
Reputation: 22562
Have a base virtual function that throws an exception (let's call it not_implemented
) in the base class.
Anyway, you generally won't want to do that. You would better have a proper class hierarchy as said in other comments.
Upvotes: 1
Reputation: 545618
This practice is sometimes called fat interface and is considered an anti-pattern.
The proper object oriented way is to provide a hierarchy of several subclasses, i.e. to separate “optional” methods into an extra interface and let only some classes implement that interface.
You test whether a class implements these methods by testing whether it’s an instance of the relevant interface.
(Incidentally, the same is true in C – although I have never used C in serious projects, I doubt that you should use NULL
function pointers there, rather than modelling a proper type hierarchy.)
Upvotes: 8
Reputation: 65506
I don't see this a valid use of C++. in C++ you should be programming to an interface. Either the metho exists or doesn't. You seem to be thinking about C++ as simply C with classes. It's a bit more.
Either the interface says there is a method or it says it doesn't. This gives compile time safety that C won't.
Upvotes: 2