3 ms·
A C++ code design note: The initial example in the article is anti-idiomatic, because it imbues the larger class with a RAIIness which can be limited to just o
by einpoklum 2y ago
A C++ code design note:
The initial example in the article is anti-idiomatic, because it imbues the larger class with a RAIIness which can be limited to just one element of it:
struct ObjectType {
int a;
double b;
void* c;
ObjectType() : a(1), b(2.2), c(malloc(30)) { }
~ObjectType() { free(c); }
};
It's only the c member that really requires any special attention. In this particular case. So, there should be something like a `class void_buffer` which is a RAII class, and then:
struct ObjectType {
int a;
double b;
void_buffer c;
ObjectType() : a(1), b(2.2), c(30) { }
};
and actually, let's just not sully the set of constructors, but rather have:
struct ObjectType {
int a;
double b;
void_buffer c;
static ObjectType make() {
return ObjectType{ 1, 2.2, 30 };
}
};
and now instead of a complicated bespoke class we have the simplest of structs; the only complexity is in void_buffer.
- nottorp 2y agoYes, that's a property of C++. It tempts you to hide complexity under several layers of classes so you can have ... more classes, i guess? And job security, because it makes the code much harder to follow for whoever didn't write it.
- daemin 2y agoIn this case it's not complexity but a useful abstraction. It abstracts the void_buffer into its own type with proper correct functions for creating, (maybe copying), moving, and destructing the buffer. With that you get a simple type that you can use elsewhere without needing to remember that you need to free() the buffer manually before the end of the scope, or needing to remember how to correctly copy or move the buffer elsewhere.
- einpoklum 2y ago"More classes" is not something detrimental in any way, in itself. You can have "more classes" while also having: * Less code overall * More reuse of classes as versatile/simple components, as opposed to a zoo of bespoke classes * Classes which are simpler to understand and with more predictable behavior This is true in the example above: With the corrected code, it's enough that I tell you "ObjectType is a simple struct; and one of its members is a buffer of untyped data". I don't have to show you the class definition; you know enough to understand what's going on. And you can use your void_buffer elsewhere.
- HelloNurse 2y agoBut compared to the example code in the article this void_buffer would be significantly more difficult to write and/or use, more verbose and less readable due to fragmentation into multiple classes, and (in view of future evolutions of the code) also less general.
- einpoklum 2y ago> would be significantly more difficult to write and/or use 1. It would be no more difficult to write and use than the larger class. After all, you can use the larger class as a void_buffer with some dummy extra fields. 2. You can put the class in a detail_ sub-namespace, or make it an inner class of ObjectType, and then people will avoid using it in other, general contexts.