Lobishomen, página personal

  • Páginas

C++ Advantages

Posted by luison.cpp en noviembre 17, 2014

Hi everyone, I’m just changing the language of my blog posts. Previously I was too lazy to write my blog posts in a foreign language, but I just realized that its harder for me to write in English because I need more practice, so I’m going to write most of my future posts in English.

The topic of this post is about how useful can be C++ if it’s used correctly.

I have heard and read many times that C++ is a fast language, but it’s too hard to maintain. I’m not sure about the origin of this myth, but I think that it became popular when Java didn’t include many of the C++ features and many users understood that these features are dangerous and it’s better to not have them in the language.

The reality is that most of these features make the language harder to learn, and many requires to be careful, but also, they can make the code easier to maintain and easier to read. Large projects are more suitable to be coded in C++ because these features can improve the code legibility.

I will show some examples here:

Pass by Value and pass by Reference

Suppose we have two classes named Acquis and Book. The class Book has these 3 public members:

int id;
string author;
string title;

And the class Acquis has these methods:

Book getBookById(int id);
void removeBookById(int id);
void addBook(Book newBook);

So, in C++ this is very straightforward, it’s obvious that the only way to modify the books from the Acquis is using addBook or removeBookById.

But in other languages that don’t have the option to pass objects by value, this situation has the issue that it’s not clear if getBookById returns a copy of the Book object or a reference to the object that is inside the Acquis, and also, it’s not clear if you can modify the Book that you just added to the Acquis or you should add a copy.

All of these should be written in the documentation, and that make the code looks harder to read, in contrast, in C++ the declaration of each method told explicitly that the Book that you get is a copy of the original and also, that when you add a new book, a copy will be stored instead of the same object.

I found this issue specially annoying when working with position and velocity vectors of bodies inside a videogame.

Also, think about the Book class, in C++ it’s clear that there are an integer and two strings, but in other languages, that two strings may be null pointers, and that’s another opportunity to cause bugs or confusions (in fact, some people prefer to never pass or return null, in order to avoid thouse kind of situations).

Pointers and References

Speaking of null, sometimes the null pointers are useful, because sometimes we want to wait to initialize an object and sometimes not all the members of a class need to be initialized.

But also, sometimes we need to have methods that receive not null objects, and it can be annoying(and also make the code harder to read and less efficient) if we check in each method call if a pointer is null or not.

C++ fixes this problem with the references (if the reader doesn’t know them, the references are similar to the pointers, but always points to a previously existing object(cannot be null) and it’s impossible to change where a reference is pointing), so, if a function call needs a not null pointer, it’s very easy to just ask for a reference.

Separation Between Declaration and Definition

Ok,  I admit, this can be annoying, but also has a huge advantage: if you just use a reference for each class, without using their former methods, it’s possible just declare the class, and that helps to have some control of which classes are using the methods of which other classes.

That’s very important if you want to code a program that respects the Law of Demeter:

http://en.wikipedia.org/wiki/Law_of_Demeter

Classes and Structs

At first, it may look silly that C++ has classes and also has structs, and both do exactly the same thing,  but this has an unsuspected advantage: programmers know the C structs and also know the encapsulation principles, so, it’s possible and intuitive to use the keyword «struct» to refer to C-like structs (all the members public, and no methods) and the keyword class to use for classes following the encapsulation principles.

It’s useful being able to distinguish between classes and classic structures.

shared_ptr and unique_ptr

I assume that many of the readers don’t know what are these things, briefly: unique_ptr is a pointer that deletes its content when it goes out of scope and shared_ptr are pointers that deletes their contents when all the copies of the same pointer are deleted from memory.

When a unique_ptr is declared inside a class, it’s clear that the class owns the pointer, so, you know that the content of the pointer will be deleted when the «parent» object is deleted and no one else should store a copy of that pointer.

When a shared_ptr is declared inside a class, that’s explicitly saying that many classes have access to that pointer, and that should be taken in account.

Hiding the Details of Some Structures

Sometimes there are structures that we want that only a single class is being able to access its contents, but we want the other classes to be able to store pointers to that structure (for example, the node of a tree).

In thouse cases, it’s possible to declare the struct in the header file, and define the struct in the cpp file, that trick it’s a pretty easy and clear form of telling other programmers not to modify that struct in other classes.

Operator Overloading

Make a lot cleaner the algebraic operations, some Java programmers think that Java doesn’t support them because they can obfuscate the code, but the reality is that operator overloading doesn’t work very well with references, it’s necessary to store the objects by value in order to make the operator overloading really useful.

Many Tools for Many Circumstances

Some programming languages are not very fast but they are very easy to read (for example, Java, C#, AS, Python) and the compilers need to make a large amount of heuristics in order to guess how to make the code perform well. These language are called «high level languages».

Other programming languages, like C or Assembler have a more direct access to the memory and the resources and can make more intelligent choices about how to do each thing. These languages are called «low level languages».

The charm of C++ is that C++ has both advantages, it can be high level  sometimes, and low level another times (and consequently, it has many forms of doing the same thing), being easier to maintain but slower in the high level parts, and harder to maintain but faster in the low level parts.

Some people don’t like the idea of mixing low level and high level, but that capability is a huge advantage, because it’s possible to use low level just in the bottle necks(less than the 5% of the code) and use the advantages of a high level language in the rest of the code.

In conclusion, if you have a team with many experienced programmers, you should consider C++ for your projects, not only for the performance, but also for the tools to make the projects easier to maintain.

Deja un comentario