Howdy everybody! I hope y’all have been having a good week, I know I sure have! It’s been a busy week with projects and Explore USC. This week, I want to highlight one of my classes from this semester that I’m really coming to enjoy: Professional C++.
Professional C++ is an upper division computer science course that is devoted to learning the technical specifics and intricacies of C++, particularly C++ 11, which is the most recently revised release of the language. While all of us in the class have worked with the language before, the goal was to learn overarching programming techniques and concepts, like recursion, singletons, factories, agents, etc. Professional C++ really consists of three main parts: learning intricacies of the language, reviewing and implementing effective patterns, and developing habits of clean and efficient code.
The first part, learning intricacies of the language, has been fascinating to me. From my previous experience with C++, there are many methods that I used to keep reference counts for memory clean-up purposes, comb through lists and maps to examine and/or edit them, along with many other tasks. In delving into the language, I’ve learned about using shared_ptr’s, lambda expressions, the Concurrency library, auto, and more. These libraries and built-in methods make these tasks so much simpler, and even improve on their functionality. Also, in learning about how C++11 and compilers processes the code, I’ve gained a much better understanding of how to manage the memory that I use, down to using bitsets and altering my data structures to decrease the memory footprint and runtime. I’ve also learned how RTTI (Run-Time Type Identification) works in the compilation of code and how I could go about disabling the default RTTI to implement my own instead. I’m looking forward to learning more about compiler parsing and writing my own compiler for a custom script.
The second part, reviewing and implementing effective patterns, gets into the common solutions used in industry to various issues that arise in programs. These techniques, like factories, singletons, wrappers, proxies, mediators, mementos, and monitors to name a few, are very efficient ways to achieve common goals in programs, but more than that they are commonly used in industry and thus simple to recognize and build off of. When working on large systems or with a group of computer scientists, or when joining an existing project and building off of pre-existing code, these patterns are extremely beneficial to decipher how the code works and understand the processes going on. This part is about taking the intricacies of C++11 and applying them to real-life examples to see how they help with the techniques and sometimes even implement these patterns entirely.
The last major part, developing habits of clean and efficient code, consists of applying the first two parts into challenging and applicable programs. For example, our first project was to build a program that could both compress and decompress files and directories using a run-length encoding method that we wrote ourselves. This program is very similar to WinRar or Microsoft’s zip system (although without the nice gui just yet). The program reads through all of the encoded data in the desired file (of any type) as a string of characters, converting as necessary. Then, it runs through this array, keeping track of streaks of common characters or streaks of uncommon characters and writing those out in a separate array as a series of the number of times the character showed up (negative for uncommon streaks) followed by the character itself (or the entire streak for uncommon characters). This would take a grouping like “aaaaabcd”, which has 8 characters, and condense it to “5a-1bcd”, which has only 6 characters.
After this, we developed a password cracker that could read in a list of hashed passwords (a way of storing the passwords in a large data structure without overwriting each other) and convert the hexadecimal number into a password. This consisted of two phases, a dictionary attack that would try to match the hashed password with a dictionary that was already loaded in and a brute force attack, which would run through every possible password up to a given number of characters and check to see if that was correct. This lab was fun to write and took advantage of multi-threading computers, using the Concurrency library to crack multiple passwords simultaneously and drastically speeding up the runtime. What really struck me about this project was how a simple temporary string object, which only takes up 32 bytes of memory, that was created for every password that was checked in my code slowed my runtime down from roughly 3 seconds to about 32 seconds. By simply removing this and adding a workaround to test the password without holding it in memory, my program ran 10 times faster!
Finally, my current project is to create a simple version of Microsoft’s Paint program. We are using the Windows Template Library along with many of the techniques we learned to create a program that can draw lines and other shapes, read in image files and edit them, undo and redo previous actions, and save out the changes to an image file. To do this, we are using patterns like a factory to generate shapes, a flyweight to hold various pen colors and widths, and shared_ptr’s to keep track of the shapes for the undo/redo functionality.
Overall, this class is a really rewarding way to learn one of the most commonly used languages in industry, develop good coding habits and readability, and learn how to effectively code in a professional setting. If any of those sound like something that interests you, definitely check it out! Until next time!