7 Quick Tips for Java Programmers Starting C++

Written by buckaroo.pm | Published 2017/09/07
Tech Story Tags: programming | java | cpp | cplusplus | software-development

TLDRvia the TL;DR App

Photo by fireskystudios.com on Unsplash

1. Avoid The new Keyword

In Java, objects are instantiated using the new keyword, so it might be natural to assume that we should use new in C++ in the same manner:

However, unlike in Java, a C++ variable instantiated with new is unmanaged, meaning that you must remember to free the memory after use.

This can be done with the delete keyword. Coming from the Java world, this seems at best inconvenient, and at worst highly error-prone! Why is an extra statement required for the C++ version, when the Java equivalent is so concise?

In C++, there are multiple ways to instantiate an object and the preferred way to do so is directly onto the stack.

When variables are allocated on the stack, they are automatically deleted once they go out of scope. This is very concise, and has great performance characteristics.

2. C++’s const is More Powerful Than Java’s final

A common pattern when designing large applications is to make values immutable. This reduces complexity by lowering the number of moving parts an application has.

In Java, we can use the final keyword to mark a reference as immutable. However, the data that is being pointed to may change. For example:

So to create truly immutable types, Java developers must mark all fields inside of a class as final:

In C++ we have the const keyword, which is far more powerful. If an instance is marked as const, then none of its members may change, even if they are not marked const in the class definition!

3. Beware of Stack Slicing!

In Java, the semantics of all objects is that they are on the heap (the reality is bit more complicated due to optimizations done by the JVM, but this is a good rudimentary understanding).

C++ is very different, because it allows the user to decide if the object should live on the heap or on the stack. Generally speaking, we should prefer the stack. It gives predictable (and fast!) performance, but it has a big limitation in that the size of each variable must be known at compile-time. This is a big problem when using inheritance.

In this example we have two classes A and B, where B is a subclass of A. Each has a function what that returns the class name.

Given these definitions, what do you think the following will do?

If you are coming from the Java world, the answer might surprise you! It turns out that when y is cast to type A and assigned to z, it takes the what method of class A.

When a stack-variable is assigned to a super-class in C++, it takes the members and method implementations of that super-class. This is because the size of a variable’s value must not exceed the size of its type. For stack-variables, the compiler just “slices” off the extra information of the sub-class.

To prevent this, variables can be pointed to instead. A pointer (or reference) always has the same size, regardless of the size of the value being pointed to.

Quick Aside: value_ptr

We released a new smart-pointer called value_ptr to make it easier to preserve value-semantics on the heap. See:

value_ptr — The Missing C++ Smart-pointer_TL;DR_hackernoon.com

4. Overload Your Operators!

Java does not allow you to define custom value-types and operators similar to int and boolean. As a result, vector and matrix implementations can be quite cumbersome!

In C++, we can just overload the + operator:

This makes vectors usable with +, just like the built-in primitives.

5. Take Advantage of Compile-time Programming

Java’s generics are incredibly simple, and for the most part are only useful for collection types. C++ templates expand the possibilities of compile-time programming considerably, and are in some ways more akin to Java’s annotations.

Recall our Vector2 class from before. If we want to implement a 3-dimensional version in Java, then we need to create a new class:

In C++, we can make this a parameter of the type, and write generic code that handles all sizes only once! Code is generated at compile-time, so the generic code is no less efficient than the hand-written equivalent.

With this generic definition, we can create vectors of any length easily:

Templates can even speed up compilation times! See our comparison below:

Comparing the Compilation Times of C++ Templates and Macros_TL;DR_hackernoon.com

6. Use auto!

Java famously lacks a variable type-inference keyword such as auto (C++), var (C#), val (Kotlin) or let (OCaml). This can make Java code quite verbose, particularly when classes like SimpleBeanFactoryAwareAspectInstanceFactory are in the wild!

With C++, the compiler can figure out many types for you, saving you some typing and making code more readable.

7. Be Prepared to Use More Libraries

The JVM, for better or for worse, gives you many platform abstractions out-of-the-box. By comparison, C++ is extremely lean. It lacks built-in support for file-systems, networking and graphics. Instead, C++ developers have to leverage libraries for this functionality.

A good library will also abstract over platform differences, giving a common set of portable functions, just like Java. Neither approach is strictly better. Java developers benefit from a more unified ecosystem, since everyone is using the same underlying APIs. C++ developers are unburdened by functionality that they do not need, but they also have to make more decisions about what to use, and spend more time integrating it. See:

Approaches to C++ Dependency Management, or Why We Built Buckaroo_C++ is an unusual language in that it does not yet have a dominant package manager (we’re working on it!). As a result…_hackernoon.com

Buckaroo

We created Buckaroo to make it easier to integrate C++ libraries. If you would like try it out, the best place to start is the documentation. You can browse the existing packages on Buckaroo.pm or request more over on the wishlist.


Published by HackerNoon on 2017/09/07