Tag Archives: C++

handle classes

This entry comes a bit late as this final week of school has been keeping me on my toes and I was a bit delayed in publishing this to being with, hopefully any readers might forgive this tardiness and the berevity of this post.

The week of the 22 Apr was a fun-filled week full of last minute touches to the project as we began to go over the different approaches to pointers.

The first of which was a simple ‘has a’ relationship in which the handle class(henceforth ‘Handle1’) contained the pointer. This approach was nice because it helped to solve the problem of memory managment (from the perspective of the main program) and pushed this down into the Handle1 object and the containing class(as its destructor invoked the destructor of the handle). The drawbacks to this implementation was that to give access to the methods of the pointer we would either have to loosen the encapsulation of the pointer or define a common interface, we choose the common interface initially.

Handle2 was the second revision in which we loosened the encapsulation instead allowing pointer like operations with operator* and operator->. The good: this allowed us to not have to define the public interface, as such allowing for non-shared methods of the interface to be invoked (after verifying the type and typcasting). The bad: by giving up the pointer we lost control of the data and the user could swap it out and then we would have the potential to leak memory.

The third and final handle(Handle3) was our attempt at a copy on write pointer encapsulation. The objective being, since we often have a spare matrix in which many cells never get written it would be nice to not have to have a unique value of a null object for each non-used cell. The overhead is that we would need to track how many locations are using the same pointer by a separate count and as such increase the level of indirection so we could modify this count only once for all instances of the pointer and then only alter the one that we need to when written

In summation it would have been nice to use a copy on write pointer that implemented the common interface for the Life project, due to deadlines we went with a similar but not optimal approach in which we had the multiple levels of indirection and a common interface but initialized all of the pointers to null objects initially.

 

Advertisements

abstract classes and methods, Life, and function binding

This week in OOP we talked about approaches to the Life project, function bindings and how to use non-default bindings in C++/Java, and abstract methods and classes.

When we talk about function binding we are referring to the function that is invoked. The bindings that we have studied this past week are dynamic and static binding, with static binding the declared class of the object/variable is the function that is invoked, with dynamic binding the type of the value that is stored in the variable or the type of the object itself determines the function that is invoked. As you might have guessed by now java uses dynamic function binding by default and C++ uses static by default. However either can have the opposite binding enabled by keywords in Java this is accomplished by the use of private methods, static methods, final methods, or final classes. In C++ dynamic binding is enabled by using the keyword virtual on the parent method, this will cause a look up table to be built and used at runtime to determine the function to be invoked.

Java has the convention that either a class can be abstract and have no abstract methods or it must be abstract if any methods are abstract. As such disallowing instantiation of the class and all subclasses that choose to not implement the abstract methods. If a method is declared abstract then it can’t have an implementation as such you end up having to create protected helper methods if desired with different names. As you might imagine C++ is a slightly different story, you can have abstract(/pure virtual) methods but they may have implementations if you choose to provide them, however the methods must be implemented in function scope. The notion of an abstract class with no abstract methods does not exist in C++ however a pure virtual destructor would give you much the same result.

darwins game of life

As the semester is rapidly coming to a close I find myself still learning new lessons in OOP. Namely what the funky syntax is that I note on some constructors (initializer lists) and that I don’t fully understand the STL data structure.

When programing we like to have certain data be available to all of the instances of a class but have only one copy, in java this is easy, simply declare a static variable. In C++ the static variables exist but they operate in a slightly different way, namely they are ‘flavor’ or class specific so a subclass has a different static variable than the superclass. In C++ if you want the static instance to be nonchanging then you can declare it final and use the syntax <class>(<params>) : <name_of_static_final_var>(<value/variable>) { <other assignments and such>} this will have the net effect of assigning the variable/value to the static var. In java you can use static initializer blocks to do a rough equivalence to this.

In working with the STL libraries my partner and I ran into an interesting issue, we wanted the board to store the creatures and we wanted to be able to move the creatures easily, as well as not have a state explosion if the population of valid creatures was small(as it normally is with respect to the board). So our first approach was to make a vector for storage and use the pointers to the elements of the vector, however after much frustration we realized that push_back can cause the vector to grow and it might but will not always change the addresses of the elements. What was curious was that on a 32 bit machine all was well, on a 64 bit machine we failed some unit tests, however if we ran the program in valgrind everything worked fine. This goes to show that some compilers helping you out can cause a lot of frustration in the long run because they effectively mask the real problem at play.