How do you do inheritance in a non-OO language? - c++

I read that early C++ "compilers" actually translated the C++ code to C and used a C compiler on the backend, and that made me wonder. I've got enough technical knowledge to wrap my head around most of how that would work, but I can't figure out how to do class inheritance without having language support for it.
Specifically, how do you define a class with a few fields, then a bunch of subclasses that inherit from it and each add their own new fields, and be able to pass them around interchangeably as function arguments? And especially how can you do it when C++ allows you to allocate objects on the stack, so you might not even have pointers to hide behind?
NOTE: The first couple answers I got were about polymorphism. I know all about polymorphism and virtual methods. I've even given a conference presentation once about the low-level details of how the virtual method table in Delphi works. What I'm wondering about is class inheritance and fields, not polymorphism.

In C anyway you an do it the way cfront used to do it in the early days of C++ when the C++ code was translated into C. But you need to be quite disciplined and do all the grunt work manually.
Your 'classes' have to be initialized using a function that performs the constructor's work. this will include initializing a pointer to a table of polymorphic function pointers for the virtual functions. Virtual function calls have to be made through the vtbl function pointer (which will point to a structure of function pointers - one for each virtual function).
The virtual function structure for each derived calss needs to be a super-set of the one for the base class.
Some of the mechanics of this might be hidden/aided using macros.
Miro Samek's first edition of "Practical Statecharts in C/C++" has an Appendix A - "C+ - Object Oriented Programming in C" that has such macros. It looks like this was dropped from the second edition. Probably because it's more trouble than it's worth. Just use C++ if you want to do this...
You should also read Lippman's "Inside the C++ Object Model" which goes into gory details about how C++ works behind the scenes, often with snippets of how things might work in C.
I think I see what you're after. Maybe.
How can something like this work:
typedef
struct foo {
int a;
} foo;
void doSomething( foo f); // note: f is passed by value
typedef
struct bar {
foo base;
int b;
} bar;
int main() {
bar b = { { 1 }, 2};
doSomething( b); // how can the compiler know to 'slice' b
// down to a foo?
return 0;
}
Well you can't do that as simply as that without language support - you'd need to do some things manually (that's what it means to not have language support):
doSomething( b.base); // this works

Basically, structs-within-structs.
struct Base {
int blah;
};
struct Derived {
struct Base __base;
int foo;
};
When you want to, say, cast a Derived * to Base *, you'd actually return a pointer to the __base element of the Derived struct, which in this case is the first thing in the struct so the pointers should be the same (wouldn't be the case for multiple-inherited classes though).
If you want to access blah in this case, you would do something like derived.__base.blah.
Virtual functions are normally done with a special table of function pointers that is part of each object, a rudimentary sort of "what is my type" record.

Here is how COM does it for C language. I am a bit rusty at this , but the essence works like this. Each "class" member variables is just a struct.
struct Shape
{
int value;
};
struct Square
{
struct Shape shape; // make sure this is on top, if not KABOOM
int someothervalue;
};
all the methods, are actually just normal functions. like this
void Draw(Shape * shape,int x,int y)
{
shape->value=10; // this should work even if you put in a square. i think...
}
then, they use the preprocessor to "trick" the C code into displaying something like this.
Square * square;
square->Draw(0,0); // this doesnt make sense, the preprocessor changes it to Draw(square,0,0);
Alas, i dont know what kind of preprocessor tricks are done to make the C++ looking function call resolve into a plan vanilla C call.
DirectX COM objects are declared this way.

Dr. Dobb's had a moderately detailed article on this topic, Single Inheritance Classes in C.

Structs-within-structs is common, but it makes it a pain to access inherited fields. You either need to use indirection (e.g. child->parent.field), or casting (((PARENT *) child)->field).
An alternative I have seen is more like this:
#define COUNTRY_FIELDS \
char *name; \
int population;
typedef struct COUNTRY
{
COUNTRY_FIELDS
} COUNTRY;
#define PRINCIPALITY_FIELDS \
COUNTRY_FIELDS \
char *prince;
typedef struct PRINCIPALITY
{
PRINCIPALITY_FIELDS
} PRINCIPALITY;
This gives types with direct access to inherited fields. The resulting objects can still be safely cast to the parent type, because the parent's fields and the inherited fields start at the same place.
The syntax can be improved a little with macros. I saw this in the older POV-Ray source (but I think they've since converted to C++).

If you want a good reference on how this stuff works take a look at the glib/gdk/gtk open source libraries. They have pretty good documentation and the entire framework is based on C OO.

You can simulate an object by writing constructors, setters, getters, and destructors with the hidden this pointer called out explicitly.
Inheritance is handled by having the derived object include a pointer to the base object in the structure of the derived object.

Related

Is dynamic_casting through inheritance hierarchy bad practice?

I have got the following data structure:
class Element {
std::string getType();
std::string getId();
virtual std::vector<Element*> getChildren();
}
class A : public Element {
void addA(const A *a);
void addB(const B *b);
void addC(const C *c);
std::vector<Element*> getChildren();
}
class B : public Element {
void addB(const B *b);
void addC(const C *c);
std::vector<Element*> getChildren();
}
class C : public Element {
int someActualValue;
}
/* The classes also have some kind of container to store the pointers and
* child elements. But let's keep the code short. */
The data structure is used to pruduce a acyclic directed graph. The C class acts as a "leaf" containing actual data for algebra-tasks. A and B hold other information, like names, types, rules, my favourite color and the weather forecast.
I want to program a feature, where a window pops up and you can navigate through an already existing structure. On the way i want to show the path the user took with some pretty flow chart, which is clickable to go back in the hierarchy. Based on the currently visited Graph-Node (which could be either A, B or C) some information has to be computed and displayed.
I thought i could just make a std::vector of type Element* and use the last item as the active element i work with. I thought that was a pretty nice approach, as it makes use of the inheritance that is already there and keeps the code i need quite small.
But i have a lot of situations like these:
Element* currentElement;
void addToCurrentElement(const C *c) {
if(A *a = dynamic_cast<A*>(currentElement)) {
//doSomething, if not, check if currentElement is actually a B
}
}
Or even worse:
vector<C*> filterForC's(A* parent) {
vector<Element*> eleVec = parent.getChildren();
vector<C*> retVec;
for(Element* e : eleVec) {
if (e.getType() == "class C") {
C *c = dynamic_cast<C*>(e);
retVec.append(c);
}
}
}
It definitely is object oriented. It definitely does use inheritance. But it feels like i just threw all the comfort OOP gives me over board and decided to use raw pointers and bitshifts again. Googling the subject, i found a lot of people saying casting up/down is bad design or bad practice. I totally believe that this is true, but I want to know why exactly. I can not change most of the code as it is part of a bigger project, but i want to know how to counter something like this situation when i design a program in the future.
My Questions:
Why is casting up/down considered bad design, besides the fact that it looks horrible?
Is a dynamic_cast slow?
Are there any rules of thumb how i can avoid a design like the one i explained above?
There are a lot of questions on dynamic_cast here on SO. I read only a few and also don't use that method often in my own code, so my answer reflects my opinion on this subject rather than my experience. Watch out.
(1.) Why is casting up/down considered bad design, besides the fact that it looks horrible?
(3.) Are there any rules of thumb how i can avoid a design like the one i explained above?
When reading the Stroustrup C++ FAQ, imo there is one central message: don't trust the people which say never use a certain tool. Rather, use the right tool for the task at hand.
Sometimes, however, two different tools can have a very similar purpose, and so is it here. You basically can recode any functionality using dynamic_cast through virtual functions.
So when is dynamic_cast the right tool? (see also What is the proper use case for dynamic_cast?)
One possible situation is when you have a base class which you can't extend, but nevertheless need to write overloaded-like code. With dynamic-casting you can do that non-invasive.
Another one is where you want to keep an interface, i.e. a pure virtual base class, and don't want to implement the corresponding virtual function in any derived class.
Often, however, you rather want to rely on virtual function -- if only for the reduced uglyness. Further it's more safe: a dynamic-cast can fail and terminate your program, a virtual function call (usually) won't.
Moreover, implemented in terms of pure functions, you will not forget to update it in all required places when you add a new derived class. On the other hand, a dynamic-cast can easily be forgotten in the code.
Virtual function version of your example
Here is the example again:
Element* currentElement;
void addToCurrentElement(const C *c) {
if(A *a = dynamic_cast<A*>(currentElement)) {
//doSomething, if not, check if currentElement is actually a B
}
}
To rewrite it, in your base add a (possibly pure) virtual functions add(A*), add(B*) and add(C*) which you overload in the derived classes.
struct A : public Element
{
virtual add(A* c) { /* do something for A */ }
virtual add(B* c) { /* do something for B */ }
virtual add(C* c) { /* do something for C */ }
};
//same for B, C, ...
and then call it in your function or possibly write a more concise function template
template<typename T>
void addToCurrentElement(T const* t)
{
currentElement->add(t);
}
I'd say this is the standard approach. As mentioned, the drawback could be that for pure virtual functions you require N*N overloads where maybe N might be enough (say, if only A::add requires a special treatment).
Other alternatives might use RTTI, the CRTP pattern, type erasure, and possibly more.
(2.) Is a dynamic_cast slow?
When considering what the majority of answers throughout the net state, then yes, a dynamic cast seems to be slow, see here for example.
Yet, I don't have practical experience to support or disconfirm this statement.

C wrapper for C++ library - what about inheritance?

So I've read Developing C wrapper API for Object-Oriented C++ code and I like the approach, which I have taken with my library - opaque handles for each corresponding C++ class; avoiding using void*
But now, I'm faced with thinking about 'interfaces', and base classes. For example, I have a class hierarchy of "channel" classes - a base class for a "channel" and derived concrete classes for, for example, serial comms, in-memory buffers, sockets, etc.
So I have:
typedef struct serial_channel serial_channel;
typedef struct socket_channel socket_channel;
typedef struct memory_channel memory_channel;
serial_channel* create_serial_channel();
socket_channel* create_socket_channel();
memory_channel* create_memory_channel();
But I want to be able to pass any one of those into a function to associate it with a 'device' object:
void associate_device_with_channel(device*, channel*);
Easy in C++, since it understands base classes. How do I approach this in the C wrapper library - what type is channel in C?
The only thing I can think of is that I must resort to void* to represent a base class?
typedef void* channel;
void associate_device_with_channel(device*, channel*);
It works, but would let me pass any pointer?
On the other extreme, I can write a set of functions matching the derived channel classes:
void associate_device_with_serial_channel(device*, serial_channel*);
void associate_device_with_socket_channel(device*, socket_channel*);
void associate_device_with_memory_channel(device*, memory_channel*);
It's very verbose, and if I have to add new channel types, I have to add new functions to the interface as well.
Is there some kind of middle ground I've been missing? - like a single function, but not void*?
There isn't any perfect approach. You're trying to make your function take some opaque handles (the ones with the appropriate base class) but not any handle type (which void* would accept), and there just isn't a thing in C for that.
If you like, you can provide a function which takes serial_channel* and returns channel*, and another one for each other channel subclass. This gets you away from unsafe C casting, and doesn't require numfuncs*numderivedclasses different channel-taking functions.
Personally, I'd just void* it. They're using C, after all... clearly they don't care too much about their language keeping them safe.
First, I would set up my structures something like this:
typedef void base_class;
struct base_class_impl
{
// base class member variables go here
}
struct derived_class
{
// base class must come first in the derived struct
struct base_class_impl base;
// derived class member variables go here
}
Then, I would take pointers to base_class as arguments to my functions:
int base_class_get_count(base_class *b);
and I would always cast at the start of the function:
int base_class_get_count(base_class *b)
{
struct base_class *base = (struct base_class *)b;
// Operate on the object now
}
This enables base_class_get_count() to work even on objects of the derived type. The downside is that it doesn't allow the derived type to override a method - you would have to go a step further, implementing your own table of function pointers which the API calls (like base_class_get_count) dispatch out to, based on the entry in the table.
If you only target GCC or Clang (I suspect that you wouldn't bother with C if you were targeting Visual Studio), one of your options is to create a union with the non-standard __transparent_union__ attribute to list the types that a function can accept. A function accepting a union parameter with the __transparent_union__ attribute will accept either that union, or any type contained in it.
union associable_channel
{
channel* a;
serial_channel* b;
socket_channel* c;
memory_channel* d;
} __attribute__((__transparent_union__));
void associate_device_with_channel(union associable_channel chan);
serial_channel* serial;
socket_channel* socket;
memory_channel* mem;
associate_device_with_channel(serial);
associate_device_with_channel(socket);
associate_device_with_channel(mem);

data hiding in C++

I have some code in C, that uses incomplete structs this way ( simplified example ):
something.h
struct something;
struct something *new_something();
int work_a(struct something *something);
int work_b(struct something *something, const char *str);
void free_something(struct something *something);
somecode.c
int some_function()
{
struct something *something;
int x;
something = new_something();
x = work_a(something);
free_something(something);
return x;
}
I was thinking, I'm basically doing C++ here, why not try write it in C++ .
The question is ( I'm new to C++ ), how do I achieve the same in C++ ? If I try to add declare a member function of an incomplete class, I get
error: incomplete type 'something' named in nested name specifier
from clang. By writing the complete class in the header, this would lose the whole point of data hiding, and changing private vars in the class would force every file including "something.h" to recompile, which I think is not needed here. I don't need the files using "something.h" to know the size of this struct / class, I'm usually fine with having just a pointer. I suspected it should look like this:
class Something;
Something::Something();
Something::~Something();
int Something::work_a(int x);
this way I could write the same thing I did in C, only shorter, and even cleaner. Any C++ coder out there wishing to enlighten this mortal C coder?
Take a look at this article: Hiding Implementation Details in C++. It should get you pointed in the direction you are looking. Note that inheritance is being used to accomplish the goal. Also understand that in C++, a struct is a class with all members having public access (includes functions, constructors, and destructors). At a minimum, the interface has to be declared a class, then inherit from that publicly in the now hidden class implementation inside the cpp file (not another header file).
On the Pimpl design pattern, check out this Stack Overflow article: pimpl idiom vs. bridge design pattern. It should also help.
One way to achieve this is through the Pimpl design pattern where you have a pointer to some private struct/class that only your implementation knows about. Your private functions use the pointer and in theory it can be mostly inlined.
When you allocate memory with new statement the compiler has to know how much data space to allocate. The data size of Something has be seen by the compiler before you can use new to create a Something instance.
Use something like this in Something.h
class Something {
public:
Something();
private:
struct HiddenData;
HiddenData* m_pHidden;
};
Use something like this in Something.cpp
struct Something::HiddenData {
int a;
int b;
};
Something::Something() : m_pHidden(new HiddenData()) {
m_pHidden->a = 1;
}

C++, please explain Classes to a Python user?

I'm trying to learn C++, Thanks to this article I find many similarity between C++ and Python and Javascript: http://www.cse.msu.edu/~cse231/python2Cpp.html
But I can't understand C++ Classes at all, they looks like Javascript prototypes, but not that easy.
For example:
//CLxLogMessage defined in header
class myLOG: public CLxLogMessage{
public:
virtual const char * GetFormat (){
return "Wavefront Object";
}
void Error (const std::string &msg){
CLxLogMessage::Error (msg.c_str ());
}
void Info (const std::string &msg){
CLxLogMessage::Info (msg.c_str ());
}
private:
std::string authoringTool;
};
Question: What is this Public/Private stuff at all!?
Edit: To be honest, I more enjoy C++ than Python, because I can learn truth meaning of everything, not simple automated commands, for example I preferred to use "int X" rather than "X" alone.
Thanks
myLOG is the name of the class. It inherits (look it up2) from CLxLogMessage and has the functions GetFormat (which is virtual and can be overridden by subclasses and called through base class pointers, look it up2), Error, and Info. It has the data member authoringTool which is a string.
The public and private stuff is access specifiers. Something in the private section can only be used by the class's member functions, and stuff in the public section can be used by anybody. There is another type of section called protected which means that only a class and its subclasses can access it, but nobody else1.
If you start adding stuff to a class without setting an access level first, it defaults to private.
You can have as many public, private, and protected sections as you want, in any order.
You need these different protection levels because you don't want other people messing with your data when you don't know about it. For example, if you had a class representing fractions, you wouldn't want someone to change the denominator to a 0 right under your nose. They'd have to go through a setter function which would check that the new value was valid before setting the denominator to it. That's just a trivial example though. The fact that Python does not have these is a shortcoming in the language's design.
All your questions would be answered if you had read a C++ book. There is no easy way out with C++. If you try to take one, you'll end up being a horrible C++ programmer.
1 You can let somebody else access private and protected members by declaring them as friends (look it up2).
2 Sorry for saying "look it up" so much, but it's too much information for me to put here. You'll have to find a good resource for these kinds of things.
Even though there's no way to give a comprehensive answer or anything near that, maybe think about it like this: classes are types. Consider this:
int n;
Here "int" is the name of a type, and "x" is a variable of type "int". There are basic types in C++, like "int", "char", "double". Now we can also make new, compound types from old types:
struct Foo
{
int n;
char c;
double d;
};
This defines a new type called "Foo", and Foo x; makes a new variable of that type. Now we can add some magic to the type "Foo":
class Foo
{
int n;
double d;
public:
Foo() : n(20), d(0.5) { } // "constructor"
};
The keywords struct and class almost mean the same thing, so we still have a compound type that has two member variables, n and d. However, this type also has a member function, and this one gets called every time you create a new Foo object. So when you say, Foo x;, then this variable's member value x.n will be set to 20 and x.d will be set to 0.5.
So that's that in a nutshell: Classes are types with built-in magic. And you are the magician.
The private and public is to do with data encapsulation, it means you can change the implementation of the class without affecting how it is used. I suggest reading up on some of the theory of object orientation.

Is it possible to subclass a C struct in C++ and use pointers to the struct in C code?

Is there a side effect in doing this:
C code:
struct foo {
int k;
};
int ret_foo(const struct foo* f){
return f.k;
}
C++ code:
class bar : public foo {
int my_bar() {
return ret_foo( (foo)this );
}
};
There's an extern "C" around the C++ code and each code is inside its own compilation unit.
Is this portable across compilers?
This is entirely legal. In C++, classes and structs are identical concepts, with the exception that all struct members are public by default. That's the only difference. So asking whether you can extend a struct is no different than asking if you can extend a class.
There is one caveat here. There is no guarantee of layout consistency from compiler to compiler. So if you compile your C code with a different compiler than your C++ code, you may run into problems related to member layout (padding especially). This can even occur when using C and C++ compilers from the same vendor.
I have had this happen with gcc and g++. I worked on a project which used several large structs. Unfortunately, g++ packed the structs significantly looser than gcc, which caused significant problems sharing objects between C and C++ code. We eventually had to manually set packing and insert padding to make the C and C++ code treat the structs the same. Note however, that this problem can occur regardless of subclassing. In fact we weren't subclassing the C struct in this case.
I certainly not recommend using such weird subclassing. It would be better to change your design to use composition instead of inheritance.
Just make one member
foo* m_pfoo;
in the bar class and it will do the same job.
Other thing you can do is to make one more class FooWrapper, containing the structure in itself with the corresponding getter method. Then you can subclass the wrapper. This way the problem with the virtual destructor is gone.
“Never derive from concrete classes.” — Sutter
“Make non-leaf classes abstract.” — Meyers
It’s simply wrong to subclass non-interface classes. You should refactor your libraries.
Technically, you can do what you want, so long as you don’t invoke undefined behavior by, e. g., deleting a pointer to the derived class by a pointer to its base class subobject. You don’t even need extern "C" for the C++ code. Yes, it’s portable. But it’s poor design.
This is perfectly legal, though it might be confusing for other programmers.
You can use inheritance to extend C-structs with methods and constructors.
Sample :
struct POINT { int x, y; }
class CPoint : POINT
{
public:
CPoint( int x_, int y_ ) { x = x_; y = y_; }
const CPoint& operator+=( const POINT& op2 )
{ x += op2.x; y += op2.y; return *this; }
// etc.
};
Extending structs might be "more" evil, but is not something you are forbidden to do.
Wow, that's evil.
Is this portable across compilers?
Most definitely not. Consider the following:
foo* x = new bar();
delete x;
In order for this to work, foo's destructor must be virtual which it clearly isn't. As long as you don't use new and as long as the derived objectd don't have custom destructors, though, you could be lucky.
/EDIT: On the other hand, if the code is only used as in the question, inheritance has no advantage over composition. Just follow the advice given by m_pGladiator.
This is perfectly legal, and you can see it in practice with the MFC CRect and CPoint classes. CPoint derives from POINT (defined in windef.h), and CRect derives from RECT. You are simply decorating an object with member functions. As long as you don't extend the object with more data, you're fine. In fact, if you have a complex C struct that is a pain to default-initialize, extending it with a class that contains a default constructor is an easy way to deal with that issue.
Even if you do this:
foo *pFoo = new bar;
delete pFoo;
then you're fine, since your constructor and destructor are trivial, and you haven't allocated any extra memory.
You also don't have to wrap your C++ object with 'extern "C"', since you're not actually passing a C++ type to the C functions.
I don't think it is necessarily a problem. The behaviour is well defined, and as long as you are careful with life-time issues (don't mix and match allocations between the C++ and C code) will do what you want. It should be perfectly portable across compilers.
The problem with destructors is real, but applies any time the base class destructor isn't virtual not just for C structs. It is something you need to be aware of but doesn't preclude using this pattern.
It will work, and portably BUT you cannot use any virtual functions (which includes destructors).
I would recommend that instead of doing this you have Bar contain a Foo.
class Bar
{
private:
Foo mFoo;
};
I don't get why you don't simply make ret_foo a member method. Your current way makes your code awfully hard to understand. What is so difficult about using a real class in the first place with a member variable and get/set methods?
I know it's possible to subclass structs in C++, but the danger is that others won't be able to understand what you coded because it's so seldom that somebody actually does it. I'd go for a robust and common solution instead.
It probably will work but I do not believe it is guaranteed to. The following is a quote from ISO C++ 10/5:
A base class subobject might have a layout (3.7) different from the layout of a most derived object of the same type.
It's hard to see how in the "real world" this could actually be the case.
EDIT:
The bottom line is that the standard has not limited the number of places where a base class subobject layout can be different from a concrete object with that same Base type. The result is that any assumptions you may have, such as POD-ness etc. are not necessarily true for the base class subobject.
EDIT:
An alternative approach, and one whose behaviour is well defined is to make 'foo' a member of 'bar' and to provide a conversion operator where it's necessary.
class bar {
public:
int my_bar() {
return ret_foo( foo_ );
}
//
// This allows a 'bar' to be used where a 'foo' is expected
inline operator foo& () {
return foo_;
}
private:
foo foo_;
};