Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ struct inheritance [closed]

As far as I know the main difference (and may be the unique one) between classes and structs in C++ is that classes have their members private by default and structs have theirs public by default.

However, and probably because I was a C-developer before, I still continue to declare structs to hold only "public" fields, and I almost never declare methods (except constructors to initialize members).

I also want to take advantage of C++ inheritance for structs.

My questions are:

  1. Even if the language allows it, is it a good practice to inherits structs ?
  2. Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?

Thank you

like image 645
Mustapha Yousfi Avatar asked Sep 21 '17 08:09

Mustapha Yousfi


2 Answers

classes have their members private by default and structs have theirs public by default.

Structs also inherit public by default, where classes inherit private by default.

Even if the language allows it, is it a good practice to inherits structs ?

Sure. It works exactly as you would expect.

Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?

Not yet. There is a proposal for C++20+ (P0707) to allow exactly this, but it's still pretty young and not implemented far enough to be used anywhere. In particular, search for "3.6 plain_struct" to see how they enforce plain structs to be that.

In general I would recommend using a struct when you're using it as a "struct" sort of function - holding data without invariants. If you have invariants, you should keep them using encapsulation and data hiding, so it should be a class.

like image 83
dascandy Avatar answered Oct 14 '22 07:10

dascandy


Just want to address this question:

Even if the language allows it, is it a good practice to inherits structs ?

You should rid yourself of connotation that "struct" indicates POD. Sometimes, the most reusable components are those that don't encapsulate anything, despite having some behavior.

For instance, consider this meta-function:

template<typename T> struct is_foo :      std::false_type {};
template<>           struct is_foo<Foo> : std::true_type  {};

All of the above types (and the types behind the aliases for true and false) are declared with the struct keyword. This is simply because having everything public by default forwards the behavior we want without us having to spell it out every time.

Another time when you find yourself inheriting from a "struct" is when extending a C library. If the library defines a structure named struct Bar that is used to communicate with it, the easiest way you can add functionality to it, is by inheriting from Bar. Like this:

class ExtendedBar : Bar {
  void mem_func() {
    //Need to call the C library function? No problem
    c_library_func(this); // ExtendedBar is-a Bar
  }
};

The only important difference is the default accessibility levels. And the only thing you should concern yourself with (IMO) is which default accessibility works best for your purpose.

like image 4
StoryTeller - Unslander Monica Avatar answered Oct 14 '22 07:10

StoryTeller - Unslander Monica