I've been mulling this over in my head lately. Most of us are well aware that in C
, in order to create a struct, you normally prefix it with a typedef
to avoid calling the struct
keyword before referencing the object. Of course, C is limited to structs rather than classes. To compensate for this, C tends to use global functions dedicated to a struct to create an object-oriented approach
For example:
typedef struct{
int foo;
float bar;
char* baz;
} SomeStruct;
Vs.
struct AnotherStruct {
int foo;
float bar;
char* baz;
};
AnotherStruct
must have the prefix keyword struct
before it, when an object of that type is declared within a function. For example:
int main( ... )
{
struct AnotherStruct obj1; //correct
SomeStruct obj2; //correct
struct SomeStruct obj3; //bad
AnotherStruct obj4; //bad
}
In terms of the object-oriented approach:
typedef struct {
//member variables here
} SomeStruct;
SomeStruct* SomeStruct_New( int a, int b, int c )
{
SomeStruct* obj = calloc( sizeof( SomeStruct ), 1 ); //not sure if that's correct -- been a while since I've used calloc.
obj.a = a;
obj.b = b;
obj.c = c;
return obj;
}
void SomeStruct_Free( SomeStruct* free )
{
free( free );
}
These functions are pretty easy to implement without the wrappers - I'm just using them for the sake of example. My point is that, given that you can already create a struct in C++ which doesn't require the typedef
to declare without the struct
keyword, and using non encapsulated functions which pertained to these structs for an object-oriented approach, I was curious to know if there are any advantages to the C approach of coding in C++, which would include using static global functions as private member functions, along with global function constructors which would return pointers to objects.
This is just mainly out of curiosity, as there are times where I feel like taking the C approach just for the sake of taking it, but this may just be a preferential thing.
It is pretty hard to understand the gist of the question. It seems to me that your main interrogation is whether:
is better than
in some situations.
No. It's equivalent.
With the exception of exceptions (!) any code that you express in C++ can be expressed in C. It is just a matter of syntactic sugar that make the C++ counterpart easier to read. And before the naysayers jump on the bandwagon, yes virtual tables can be emulated in C.
Still, I would rather use C++. Compiler-checked encapsulation (private
), compiler-driven overload selection, compiler-boilerplate (templates). It is just syntactic sugar, but such sweet sugar.
That being said:
class Foo {
Foo() {}
friend Foo build(int a, int b);
friend int getA(Foo const& foo);
friend int getB(Foo const& foo);
int a;
int b;
};
can be thought of as Object Oriented.
EDIT: simple and dummy example of polymorphism.
#include <stdio.h>
// Interface
typedef void (*FunctionPrint)(void const*);
typedef struct {
FunctionPrint print;
} PrinterInterface;
void print(void const* item, PrinterInterface const* pi) {
(*pi->print)(item);
}
// Foo
typedef struct { int a; } Foo;
void printFoo(void const* arg) {
Foo const* foo = (Foo const*)arg;
printf("Foo{%d}\n", foo->a);
}
PrinterInterface const FooPI = { &printFoo };
// Bar
typedef struct { char* a; } Bar;
void printBar(void const* arg) {
Bar const* bar = (Bar const*)arg;
printf("Bar{\"%s\"}\n", bar->a);
}
PrinterInterface const BarPI = { &printBar };
// Main
int main() {
Foo foo = { 1 };
Bar bar = { "Hello, World!" };
print(&foo, &FooPI);
print(&bar, &BarPI);
}
Result:
Foo{1}
Bar{"Hello, World!"}