Callbacks, Objects and Private Methods in C?

I’ve been tinkering with C  for a few hours after getting a bit tired of all the OOP and C++.  I just tried to do some high-level stuff, and here’s one or two ideas that worked. I don’t recommend any C++ developers to start using these instead of the good old OO System. That would be re-inventing the wheel. I’m just sharing these because they seem interesting.

pro_lang.h

/* header guards etc. */

typedef struct _Pro_Object Pro_Object;

struct _Pro_Object
{
    /* members */
    int money;

    /* callbacks */
    void (*on_print)(Pro_Object*);
    void (*on_start)(Pro_Object*);
};

Pro_Object* pro_object_new( void );

/* inline functions */
#define pro_object_set_money( obj, v ) obj->money = v
#define pro_object_get_money( obj ) obj->money

/* methods */
void pro_object_print_money( Pro_Object* );
void pro_object_start_up( Pro_Object* );

pro_lang.c

/* Simply declare private methods as 'static'
   in your source file! */

static void pro_object_init( Pro_Object* obj );

Pro_Object* pro_object_new( void )
{
    Pro_Object* obj = (Pro_Object*) malloc( sizeof( Pro_Object ) );
    pro_object_init( obj );
}

void pro_object_init( Pro_Object* obj )
{
    obj->money = 0;

    obj->on_print = NULL;
    obj->on_start = NULL;
}

void pro_object_start_up( Pro_Object* obj )
{
    if ( obj->on_start ) ( *obj->on_start )( obj );
}

void pro_object_print_money( Pro_Object* obj )
{
    printf( "\nMoney : %i \n", obj->money );
    if( obj->on_print ) ( *obj->on_print )( obj );
}

main.c

void print_callback( Pro_Object* obj )
{
    printf( "THIS IS A PRINT CALLBACK! \n" );
}

void start_callback( Pro_Object* obj )
{
    printf( "\nTHIS IS A START CALLBACK! \n");
}

int main()
{
    /* constructor */
    Pro_Object* obj = pro_object_new();

    /* testing the methods and inline functions */
    int tmp = pro_object_get_money( obj );
    printf( "Default Money Value: %i \n", tmp );

    pro_object_set_money( obj , 23 );

    tmp = pro_object_get_money( obj );
    printf( "New Money Value: %i \n", tmp );

    /* setting the callback functions */
    obj->on_print = print_callback;
    obj->on_start = start_callback;
    
    /* these will call the callback functions */
    pro_object_start_up( obj );
    pro_object_print_money( obj );

    /* destructing */
    free( obj );

    return 0;
}

Output

Default Money Value: 0
New Money Value: 23

THIS IS A START CALLBACK!

Money : 23
THIS IS A PRINT CALLBACK!

I hope to learn more about C’s latent potential and the various creative ways of unleashing it. I’ll post more discoveries…. as soon as I discover them 8-) .

Idiotic guide to the Bridge Pattern

An idiotic post teaching you my solution to the Bridge Pattern and other nonsense.

The bridge pattern is a design pattern used in software engineering which is meant to “decouple an abstraction from its implementation so that the two can vary independently”. The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes. ~Wikipedia

So here is my solution:


The “Stupidity” Class


abstract class Stupidity{
	Idiot idiot;
	
	public void setIdiot(Idiot idiot){
		this.idiot = idiot;
	}
	
	public abstract void printQuality();

	public void doAction(){
		System.out.println(idiot.getAction());
	}
}

“Ignorance” and “Foolishness”, both derived from Stupidity

class Ignorance extends Stupidity{
	@Override
	public void printQuality(){
		System.out.println("I am ignorant!");
	}
}

class Foolishness extends Stupidity{
	@Override
	public void printQuality(){
		System.out.println("I am a fool!");
	}
}

The “Idiot” Interface

interface Idiot{
	public String getAction();
}

Implementations of “Idiot”

class FatIdiot implements Idiot{
	@Override
	public String getAction(){
		return "Idiotically Fat!";
	}
}

class ThinIdiot implements Idiot{
	@Override 
	public String getAction(){
		return "Idiotically Thin!";
	}
}

The “main” method, demonstrates the above

public class Main {
	public static void main(String[] args){
		Stupidity stupidity = new Ignorance();
		stupidity.printQuality();
		
		stupidity.setIdiot(new FatIdiot());
		stupidity.doAction();
		
		stupidity.setIdiot(new ThinIdiot());
		stupidity.doAction();
		
		stupidity = new Foolishness();
		stupidity.printQuality();
		
		stupidity.setIdiot(new FatIdiot());
		stupidity.doAction();
		
		stupidity.setIdiot(new ThinIdiot());
		stupidity.doAction();		
	}
}

Output:

I am ignorant!
Idiotically Fat!
Idiotically Thin!

I am a fool!
Idiotically Fat!
Idiotically Thin!

As you can see, the bridge pattern makes “Stupidity” more flexible, different implementations of “Idiot” can literally be plugged into it. Which makes it more generic and improves design.

Community

Follow

Get every new post delivered to your Inbox.

Join 211 other followers