DEV Community

Discussion on: Getting Cozy With C++

Collapse
 
pgradot profile image
Pierre Gradot

Hey!

A few (other) comments that may help :)

"C++ has structs and classes, but they're almost identical. The only difference is the default visibility: structs are public, classes are private, but through explicit annotations they're functionally equivalent otherwise."

Before talking why we have both, I wanted to point about a second important difference (this is not clearly said in your sentence): default inheritance is not the same. See here:

"If access-specifier is omitted, it defaults to public for classes declared with class-key struct and to private for classes declared with class-key class."

Try to modify the solution code to replace struct with class and see when it compiles and when it doesn't:

struct Foo {};

struct Bar : Foo {};

void doSomething(const Foo&);

int main() {
    Bar bar;
    doSomething(bar);
}

So "why struct AND class?". Well... C++ came from C and was supposed to be compatible. So we have struct and class for this reason only. Sorry.

From my experience, there is no real reason to use one why over the other. A quite common way is indeed to use struct for basic data type, where all members are public (and most of the time with no member function). Example:

struct Point {
  int x
  int y;
};

Class is used when you are modeling an object with behavior:

class NetworkConnection {
public:
   // ctor(s)
   void open();
   void close();
   void setTimeout(int);
private:
   // we don't care this is private
};

This is just a convention, there is no technical reason. Do what you want, simply be coherent.

By the way:

typedef struct Cell
{
    // ...
} Cell;

This is C-style code! Get rid of this typedef :)

struct Cell
{
    // ...
};

Finally:

"The biggest takeaway for me was that if you just use a pointer to a specific object, you don't need to actually include it, you can (and probably should) just forward-declare it."

First: try to use references at much as possible. If not possible, try to use smart pointers as much as possible.

Second: be prudent with this technique. Remember that including your class header should be enough for client code to compile. If you forward-declare a type in your HPP that is only needed in your CPP for the class implementation, no problem. If class users must also include the good headers, this can be painful.

Example with Foo.hpp:

#pragma once

class Foo;

struct Bar {
   Foo* foo;
};

If I include Foo.hpp in mySource.cpp, it won't compile. And I will have to wonder what other files I should include.

This may sound obvious but I saw code like this in real life...

Good luck with C++ ^^