Archive | Object Oriented RSS for this section

Operator Overloading in C++

My thoughts on Operator Overloading are hardly a secret. Some languages, such as Haskell, support it in a sane manner. Some languages, such as C++ don’t. Either way though, I’m not a fan.

That said, there is one case where I support it; when what you are trying to overload an operator to do makes sense for your type. In other words, if it makes sense to multiply an Employee object, feel free to overload the multiplication operator. Since we don’t usually model mating when we implement an employee object, I don’t usually approve.

Multiplying a Fraction

However, if we have a fraction class, that has a numerator and denominator component, overloading the multiplication operator suddenly becomes reasonable:

frac<T> operator *(const frac<T> & rhs) const { return frac<T>(numer * rhs.numer, denom * rhs.denom); };

In C++, many of the built in operators are available to be overloaded. You can do basically anything in an operator overload, but if you do, that makes you a bad person. Here we have a straightforward implementation, that I’m going to assume you don’t need to have explained to you. But let’s talk const correctness.

In this signature, the const appears twice. The right hand side argument is a const reference. Since this is a reference, no copy occurs, but with references can come mutability. The const here prevents any mutation from occurring. There is also a const at the end of the signature. That means that this function cannot modify the this pointer.

This function returns a new frac<t>, so no need for const there.

Convert a Fraction to a Double

Next, you can overload the casting operator, and if you are a good person you’ll use this for type conversions. Let’s implement (double) for our fraction:

operator double() const { return (double) numer / denom; }

This code is pretty straight forward. We divide the numerator by the denominator, and cast it to double in case integer division occurs. Cast operator overloads don’t have a return type, which is a bit strange but something we can work with.

Streaming operators

Finally, I’d like to talk about streaming operator overloads. For any overloaded operator, there are two forms: member and non-member. Member overloads take n - 1 arguments, where the minus 1 is the current object (and the left hand side). Non member overloads can’t access the this pointer, so they need to take the left hand side as a parameter.

Member overloads obviously have access to private class members, which makes them more powerful than non-member. Which leads us to the streaming operators. Streaming operators need to return std::ostream &, so they must be non-member. The problem is that we want to print the private numerator and denominator fields. The solution? make it a friend:

friend std::ostream & operator <<(std::ostream & lhs, const frac<T> & rhs) { lhs << rhs.numer << '/' << rhs.denom; return lhs; };

With that problem solved, this function becomes pretty straight forward. We stream the fields, formatted correctly, into the left hand side std::ostream &, then we return the left hand side argument for further use by the next part of the streaming chain.

Back in the Saddle with C++

Next quarter, I’ll be taking a graphics programming class. It was a year ago to the day that I last wrote about getting a makefile set up for OpenGL development. As you can imagine nothing came of it. Why? The obvious answer is that OpenGL is hard.

Secondary answers include the fact that almost all of the literature is assuming C++, and I was swimming against the tide trying to use C. Well, I won’t have a choice this time, the class is in C++, so I’m stuck with my old nemesis again.

What follows in the next few posts is an attempt to refamiliarize myself with C++. It’s been a while since I’ve done any significant work in C++ and a lot has happened. I’ll be going over a lot of basic stuff, so that I have a centralized crash course for myself when I’m stuck trying to remember if it’s const &, & const, & const &, or co&n&st (stranger things have happened).

Namespaces

First up: namespaces. Namespaces are a formalization of the c convention of writing functions called stuff like dmp_doStuff. First we can declare our namespace:

namespace dmp { void doStuff() }

…and we can call this function by doing dmp::doStuff(). This may involve an extra keystroke, but we can also use it like so:

using namespace dmp; doStuff(); doStuff(); doStuff(); while (stuffUndone()) doStuff;

<Template> Classes

Now that we got that out of the way, let’s get into the meat of it: template classes. First up, due to some incredibly unfortunate reason, a C++ template class has to go in the header file. This sad fact is one of C++’s many transgressions against society, but we’ll not worry about that for now.

To declare a class (inside of a namespace if you’re a good citizen):

namespace dmp { template <typename T> class frac { public: /* public stuff goes here */ private: T numer; T denom; /* and your privates go here */ }; }

template <typename T> would be omitted if this weren’t a template class. Here we declare a class frac with one generic type T. Our class has two private fields of type T. As we all know, class members are private by default, but I don’t like to rely on “default behaviors”, so it doesn’t hurt to make it explicit. Let’s add some public constructors:

frac(T inNumer, T inDenom) : numer(inNumer), denom(inDenom) {}; frac(const frac<T> & toCopy) : numer(toCopy.numer), denom(toCopy.denom) {};

Here we use initializer lists to populate the numerator and denominator. The first constructor takes two arguments of the same type (T), and the second is the copy constructor.

According to Microsoft, initializer lists are more efficient than assignment in the function body, which is why we prefer them here. There are certain cases where you must use an initializer list, and cases where you cannot use them. Your compiler will tell you if you mess this up.

Finally, let’s add a destructor:

~frac() {};

Here we have a marvel of software engineering. Since we really don’t have anything to destroy, we can let it do nothing. It should be noted that this destructor is not virtual, so it’s not really safe to extend this class (more on this another day).

Conclusion

Honestly, namespaces and constructors/destructors are two of my favorite features of C++. Simple, but helpful in eliminating boilerplate. I almost might be convinced to compile “C” with a C++ compiler to get these features. Coming up will be some features that I’m a bit more iffy about, such as operator overloading. however, when used appropriately, these things can also be good, more to come!

Everything Is An Integer

Today I found myself plumbing the murky depths of C++. My latest task: file IO.

C++ provides a type fstream. Being a proper object-oriented system, the class hierarchy is completely indecipherable. However, the actual use of this type is fairly simple. An instance of fstream has a “get pointer” and a “put pointer”. To write to the file, you must seek the put pointer to a location, then write. To read, you must seek the get pointer, then read. Fairly simple, right?

The seek methods: seekp and seekg are overloaded:

ostream& seek[pg] (streampos pos); ostream& seek[pg] (streamoff off, ios_base::seekdir way);

Should be no problem, right? Let’s de-typedef-ify that:

ostream& seek[pg] (int pos); ostream& seek[pg] (int off, int way);

Ok, still no big deal. This is C++ after all, enums are integers. So, I carry on my merry way. I implemented the following functions:

template <class to_write> static void write_out(fstream * fio, offset location, const to_write & value) { fio->seekp(location, ios_base::end); write_out<to_write>(fio, value); } template <class to_write> static void write_out(fstream * fio, const to_write & value, streampos position) { fio->seekp(position); write_out<to_write>(fio, value); } template <class to_read> static void read_in(fstream * fio, to_read & into_location) { ...stuff... }

The idea: wrap the seeking and writing into one operation, so my high level code need not concern itself with it. The behavior:

write_out<long>(foo, 8, ios_base::beg);

…and…

offset bar = 0; write_out<long>(foo, bar, 0);

…both result in the first function being called! Were this a language with a proper type system, all those types would be distinct and the function overloading would work as advertised. Unfortunately, this is C++, where there is only 1 type: byte.

Let this serve as a warning, so you don’t spend half your day troubleshooting such a stupid problem.

Object Oriented Haskell

You may recall, earlier this year I wrote about object orientation in C. The basic Idea being that “Object Oriented Programming” is more a mindset, then a language feature. You can do object orientation and access control in C using free-floating functions and opaque structs. Well, guess what? You can do Object Oriented Programming in Haskell as well!

As a quick recap, if you didn’t read "C With Classes", for our purposes there are three components that need to be present to be considered “an object”: data consolidation, access control, and method calling. Inheritance is also important to real “Object Oriented Programming” (or OOP, as I’ll start calling it), but is really just gravy. Inheritance is largely supported by typeclasses in Haskell, so I won’t be going into it today.

Functional OOP

What would OOP look like in Haskell? Thanks to the magic of higher-order functions, we can actually very closely approximate what you’d see in a traditional OOP language, such as Java or C++.

Data

This part is trivial, there is literally a data keyword for this purpose. You should have this down by now.

Access Control

Access Control can be accomplished by way of the module keyword. Simply expose what you’d like to be public, and don’t expose your private members. Obviously, if you have private fields in your “Class”, you should make a factory function for your class instead of exposing its constructor. This is all pretty standard stuff.

Method Calls

This is an area that Haskell shines, and C shows its ugly side. In Haskell, we can actually create a method call operator, and create something that looks very much like the traditional Class.method calling convention that we’re used to!

The Method Call Operator

First, we need some contrived classes. Let’s go with everybody’s favorite: the Employee!

data Employee = Employee {name :: String, employeeId :: Integer, title :: String}

Nothing fancy or non-standard here. We created an Employee “Class” in the traditional Haskell way. Due to our use of record syntax, we already have three getters: name, employeeId, and title.

Let’s make another function, so that we can have a method that takes arguments:

isSeniorTo :: Employee -> Employee -> Bool isSeniorTo s f = (employeeId s) > (employeeId f)

There is something extremely important to note about this function: the last argument is the object, not the first as it was in “C With Classes”. The reason for this is to allow us to partially apply this function, this will be crucial.

Now, let’s give it a shot to make sure everything is working:

*ghci> let boss = newEmployee "Chris" 1 "Author" *ghci> let notBoss = newEmployee "Geoffrey" 2 "Associate" *ghci> name boss "Chris" *ghci> isSeniorTo notBoss boss True

All looks well, we create two Employee objects. Since Chris‘s employee ID is lower than Geoffrey‘s, the isSeniorTo method returns True. But this is all very wonky still, let’s create that method call operator already!

(>-) :: a -> (a -> b) -> b (>-) o f = f o

Since . and -> are already spoken for, I’ve gone with >- for my method call operator. The method call operator takes an arbitrary type a, and a function that takes the same type a, and returns a type b. Finally a type b is returned. The definition of this function couldn’t be simpler: we call the function on the passed-in object! Let’s see this in action:

*ghci> notBoss >- title "Associate" *ghci> boss >- isSeniorTo notBoss True

This is just about as elegant as it gets; using the method call operator we just defined, we call a method on an object! In the case of isSeniorTo, we partially apply the function with all but the last argument, then the method call operator is able to use it just as any other function.

But something doesn’t sit right. Isn’t the definition of isSeniorTo a bit smelly? It calls methods on objects, shouldn’t it use the method call operator? Now that we have our method call operator, let’s fix that function:

isSeniorTo :: Employee -> Employee -> Bool isSeniorTo s f = (s >- employeeId) > (f >- employeeId)

There, that’s better. isSeniorTo now properly calls methods on s and f, and all is again well in the world.

Here’s The Kicker

You may be experiencing some deja vu from all of this. It feels like we’ve done this sort of thing before. But where? You may recall this little operator:

*ghci> :t (>>=) (>>=) :: Monad m => m a -> (a -> m b) -> m b

That’s right, the monadic bind operator looks suspiciously like our method call operator. But does it behave the same?

*ghci> 1 >- (+) 1 2 *ghci> Just 1 >>= (\a -> return $ a + 1) Just 2

Let’s ignore for a second that we had to use a monad for the bind operator, and see the fact that the two basically did the same thing. In fact, to further illustrate the point, let’s make a Class monad:

data Class a = Class a deriving (Show) instance Monad Class where (Class a) >>= f = f a return = Class

Unlike most monads, which do important work, our Class monad does nothing but prove a point. However, you should note that the implementation of the bind operator is essentially the same as the implementation of the method call operator. Now, let’s see our monad in action!

let boss = Employee "Chris" 1 "Author" *ghci> boss >- name "Chris" *ghci> Class boss >>= return . name Class "Chris"

As you can see, they essentially do the same thing. It turns out that Haskell had classes all along!

Of course, this isn’t exactly true. I’d say that the State monad serves many of the same purposes as objects in OOP languages. However, the semantics of things like Reader, Maybe, and IO have little in common with objects. But much like we implemented Objects in Haskell, the various OOP languages are implementing monads into their standard libraries.

Indeed, OOP and functional programming are not supported by languages, they are supported by programmers. Some languages may make one or the other easier, but the differences are small, and get smaller as time passes.

On ArrayLists and Vectors

Long ago, when I first started doing Java, I struggled against Java’s limitations regarding the resizing of arrays. Eventually after poking around for solutions, I found the ArrayList. Before that, I found the Vector, but for whatever reason, NetBeans was saying that Vector was deprecated, so I settled on ArrayList, and it was fine.

A few years later, I took my first class on C++, and learned about the std::vector. I was also introduced to the concepts of the vector and the linked list. Needless to say, I was confused. If vectors and linked lists aren’t the same thing, then what is this ArrayList thing? At the time, I elected not to pursue the question, needing to focus on figuring out these “pointer” things they were making us learn. I put it out of my mind.

Flash forward to today. This morning I was travelling the internet, and I came across a forum thread. The topic of the ArrayList came up. Curiosity finally overcame me, and I looked into the issue.

So, About Those ArrayLists…

The Java Collections framework is broken up into various datatype interfaces. There is an interface for lists, queues, maps, sets, and deqeues.

You’ll notice that there is no vector interface. While a list and an array have different semantics and use cases, you can use them roughly in the same way. “Array indexing” can be implemented on a list by iterating to the nth node, and arrays can be traversed like a list. Since there’s nothing a list can do that a vector can’t and vice versa, it follows that they can both implement the same interface. Sun had to make a choice: name that interface “list” or “vector”. They went with list.

Given that Java’s vector type implements the list interface, it follows that they would reflect that in the name: ArrayList. For all intents and purposes, ArrayList is equivalent to C++’s std::vector. ArrayList implements the Collections framework’s list interface, but it is a growable array. It behaves like a vector, indexing is cheap, resizing is expensive. Java also provides a LinkedList that behaves like a linked list.

So, what about Java’s Vector? It seems that Vector predates the Collections framework. After the introduction of the Collections framework Vector was retrofitted to be a part of it, also implementing the list interface. So, what’s the difference between ArrayList and Vector? Vector is synchronized, and therefore is safe to use in threaded code. Due to this it is significantly slower than ArrayList.

Simply put: use ArrayList in single-threaded code, and Vector in multi-threaded code.

Why Names Matter

This is why names matter. One might not think much of it, but imagine how many hiring managers would be out an interview question if ArrayList and Vector had been named Vector and SynchronizedVector respectively?

DMP Photo Booth 1.0

Well, the day has come and gone. DMP Photo Booth’s final test on June 21st went off without issue, and DMP Photo Booth has left Beta and is now considered “production ready”. The initial 1.0 release can be found on GitHub.

The significance of June 21st is the very reason DMP Photo Booth was created; the 21st is the day of my wedding. My wife wanted a photo booth for the reception. We looked into renting a photo booth, but it turns out that they run around $1,000. I turned to open source. Some quick googling turned up some options, but they were all personal projects or out of date. Sure I could get somebody else’s project working, but what’s the fun in that? I decided that we didn’t need to rent one, or download one, I could build it!

In late 2013, I set to work in earnest. I had a couple of months of downtime in school, and since I’m not currently working it was the perfect time. I decided I had three main objectives for this project: get some arduino experience, get some GTK+ experience, and do this all as portably as possible. I had initially decided to mostly ignore GLib and focus on GTK, but slowly I grew to appreciate GLib for what it is: the standard library that C never had. First I used GModule to handle shared libraries in a portable manner. Next I decided to use GLib primitives to keep from having to deal with cross-platform type wonkiness. Next, having grown tired of dealing with return codes, I refactored the project to use GLib’s exception replacement: GError.

Lessons Learned

It’s not all roses and puppies though. There are certainly things I’d do differently. DMP Photo Booth is developed in an Object Oriented style, passing opaque structs with “method” functions that operate on them. Each component of the program are organized into their own source file with file scoped globals scattered throughout. Said globals are protected by mutexes to create a semblance of thread safety. That said, threading issues have been a major thorn in my side. Long story short: I regret this design choice. While I still feel that this is the correct way to structure C code, and that if globals are required, this is the correct way to handle them; I feel that I should have made more of an effort to limit side effects. Recently, I’ve spent some time doing functional programming, and if I could do it again I’d try to write in a more functional style. Fortunately for me, this is something that a little refactoring could help with.

Additionally, one thing I thought would be a major help is something that began to be a major thorn in my side: NetBeans. As the size of the project grew, NetBeans got slower and slower. It seemed that I spent more time fiddling with IDE settings than actually coding. Even worse is that the IDE-generated makefile is so convoluted that it’s extremely difficult to modify by hand in a satisfying way. I’ve always coded with and IDE so I wouldn’t have even considered not using one, but then I spent some time with Haskell. One of Haskell’s “problems” is that it doesn’t have good IDE support. It doesn’t seem like any IDE really handles it well, so most people use Emacs. Personally, I haven’t really warmed up to Emacs, but GEdit has syntax highlighting for Haskell and a built-in terminal for GHCI. GEdit also has syntax highlighting for C. Next time, I will seriously consider using a lighter-weight text editor for a C project. All this said, I think NetBeans for Java remains the way to go.

What’s Next

Like any program, version 1.0 is just one of many versions. There certainly remains a lot of work to do with DMP Photo Booth. Some major items you are likely to see whenever I get around to working on DMP Photo Booth some more:

Options Dialog

I think anybody who has seen it will agree: the options dialog in DMP Photo Booth is bad. It’s poorly organized, and kind of wonky. Personally, I modify settings using the .rc file, which is telling. This is certainly a high-priority improvement.

Functional Refactor

Like I said above, the code could use a pass to limit side effects. Funtions need to have their side effects limited, and globals need to be eliminated unless absolutely necessary. However, C is not a functional language. While one could argue that function pointers enable functional programming in C, this is a very pedantic argument. I won’t be going crazy with functional programming techniques. There will be no Monads, or for loops being turned into mappings of function pointers.

Optional Module API

An idea I’ve had on the back burner for a while is an optional module API. This would be used for very specific quality-of-life things. For instance, a module could provide a GTK widget to be shown in the options dialog. Any module that doesn’t want to implement any or all of the optional API can just ignore it. The module loading function will gracefully handle the dlsym failure, just treating it as it is: declining to implement the API. I have no plans to change the current existing API, so all you module developers can rest easy!

User Interface Module

It occurred to me that it might be good to have a UI module. This would provide the UI, and wouldn’t be tied to the trigger/printer/camera module start/stop system. This module would be loaded at startup and unloaded on shutdown. This would allow the Photo Booth to use different widget toolkits: QT, Curses, Cocoa, WinForms, or whatever else. Under this scheme, the current GTK+ interface would be abstracted into the reference UI Module.

C With Classes

No, I’m not taking an ignorant view on the nature of C++, I mean exactly that: C, with classes. “But C doesn’t have classes” you say. Technically you would be right.

One of the things I find great about C is that while it is very simple, you can build anything with it. An analogy that I’m fond of is Lego. If programming is like Lego bricks, then C is the basic tub of square bricks. They are simple, and universally useful.

Meanwhile C++, Java, C#, and whatever other fancy, “feature rich” langauge you can think of are like the specialized kits. They come with all sorts of fancy curved and bendy pieces. These pieces can be used to make some cool things but are only useful in very specific situations. If you’ve ever played with Lego, you know that the fancy kits still come with a few regular square bricks.

One might think you’d need the fancy slanted bricks to make a truly intricate model, but one would be wrong. If you scale things up, your basic square bricks can create just as intricate models as any fancy kit.

Back on the subject of programming, many large projects these days make heavy use of object-oriented features. Data is logically grouped into objects, which have behaviors. This model of programming is facilitated by “Object-Oriented” languages, which have these types of structures built into the language.

C does not have a class keyword, and classes are not built into the language. This doesn’t mean that you can’t do object-oriented programming in C.

What Constitutes a Class

Books have been written about this topic, and given the audience of a programming blog, you’ve probably already read one or two of them. The main goal of a class is to centralize related data and logic into a single unit, and to insulate the rest of the program from it. A class contains data describing what it is and what it does, and has methods that act on that data. The class keeps this data hidden as much as possible from the rest of the program. A printer class might need to keep a bunch of state data, but the rest of the program doesn’t need to know about that. All the rest of the program needs to know is if the printer class is ready to accept a job, and how to tell the printer class to print.

This is called separation of concerns, and it’s good because it prevents the user of a class from getting bogged down in the nitty-gritty of an operation.

Meanwhile, C has structs. A struct has no access control, and no methods. Anybody who has ever attempted to deal with something like termios know what a nightmare this can become.

I’m here to tell you that it doesn’t have to be this way.

What Could Be

What should object-oriented programming look like in C? To answer that question, let’s really break down the idea of a class. At the core, a class has three parts: methods, data, and access control. Data is state that a class maintains, methods are functions that act upon a class, and access control is how a class decides if the outside world should be able to see data or a method. All three of these things can be accomplished in C.

Data

This is the easiest part. Data can be grouped in C using a struct, and this is how we will be doing it.

Methods

Now things are getting a bit trickier. While C has function pointers, and these can be stored in a struct, this is not how we will be doing it. In most object-oriented languages, you can access a this within the body of a method to access data within the class. You can think of this as an implicit extra argument to the function. Similarly, to approximate methods within C, we will be using functions. The first argument to any “Method” should be a pointer to the data struct.

Access Control

This is accomplished by way of an “opaque struct”. That is, a struct that is forward declared in the header, but without a definition. This struct can be passed around, but its members can’t be directly accessed because they haven’t been forwardly declared. In this manner, we approximate private data. If we want our class to have public fields, we can forwardly declare a transparent struct. This struct should have a pointer to a second opaque struct that will serve as its private data.

A Contrived Example

This is all a lot clearer with an example. First let’s take a look at the header for class contrived:

typedef struct _contrived { int first; struct c_priv * priv; } contrived; contrived * dmp_contrived_new(int first, int second, int third); void dmp_contrived_free(contrived * to_free); int dmp_contrived_sum(contrived * ths); int dmp_contrived_get_second(contrived * ths); void dmp_contrived_set_second(contrived * ths, int to_set);

First, we have our class struct. Class contrived has 1 public field, first, and a pointer to an opaque private struct. Users of this class can directly access first, but they can’t access anything within the private area.

Next we have a constructor and a destructor. If a user of the class wants to create or delete a contrived, they would not use malloc and friends, they would use the constructor and destructor. This solves another problem of C, complicated manual memory management.

After that, we have three methods: dmp_contrived_sum, a method on contrived, and a getter and setter for second, a private field. Similar to any other object-oriented language, we are free to break our encapsulation by providing getters and setters.

Now, let’s take a look at our implementation:

struct c_priv { int second; int thrid; };

First we have the definition of the private area. Since this is only in the .c file, it is not visible to the rest of the program.

contrived * dmp_contrived_new(int first, int second, int third) { contrived * working = malloc(sizeof(contrived)); working->first = first; working->priv = malloc(sizeof(struct c_priv)); working->priv->second = second; working->priv->thrid = third; return working; }

Next we have our constructor. It takes care of calls to malloc, and data initialization. When it’s done, it returns the newly created pointer.

void dmp_contrived_free(contrived * to_free) { free(to_free->priv); free(to_free); }

The destructor ensures all memory is freed. This way, a user never needs to worry about freeing data. Since this pointer has a pointer in it, it would be very easy to forget the nested pointer and leak memory. This problem is solved by taking the responsibility away from the user.

int dmp_contrived_sum(contrived * ths) { return ths->first + ths->priv->second + ths->priv->thrid; } int dmp_contrived_get_second(contrived * ths) { return ths->priv->second; } void dmp_contrived_set_second(contrived * ths, int to_set) { ths->priv->second = to_set; }

Finally, we have our contrived methods. They deal with the nitty-gritty of struct manipulation, much like traditional class members.

You may have noticed that I do not have any private methods. This is also very easy to implement; just create a static function in the same .c file. This function will not be visible outside the file it resides in, making it private.

What About Inheritance?

This is also possible in C. Basically, you can just include a pointer to a base class object in a derived class object. There also frameworks such as GObject that can facilitate this in a more robust way.

However, if you find yourself making heavy use of inheritance, I cannot advocate the use of C over a traditional object-oriented language. “Inheritance” in C makes heavy use of void pointers, and this vastly degrades the type safety of your program. While it can be done, and even done safely if you try hard enough, I feel that it is no longer worth it. Object oriented languages with these features built into them will vastly improve your productivity at this point.

But if your program just makes use of a few of your own classes, and those provided by libraries, then there’s no reason you should feel obligated to use an object-oriented language. Indeed, for basic objects, C is more than enough for anybody.

%d bloggers like this: