Use case
I have a Node class that reads, creates and sends Message objects to other Node classes. I do not wish to modify the Message class constructor because I use it in other classes as well.
Message objects basically look like that (Message.hpp file)
class Message {
size_t size;
char* buffer;
Message(size_t capacity) : buffer(new char[capacity]), size(0) {}
}
A use case could look like that (.cpp file)
Node::Node() : header_size(sizeof(int)) {}
Node::processMessage(const unique_ptr<Message>& message){
vector<Event>& events = readEvents(message); // reads the char* buffer
const int message_id = readMID(message); // reads another part of the buffer
vector<unique_ptr<Message>> messagesToSend;
for (const Event& event : events){
unique_ptr<Message> message(new Message(header_size + sizeof(Event));
writeInMessage<Event>(message, event);
writeInMessage<int>(message, message_id);
messagesToSend.push_back(std::move(message));
}
sendMessages(messagesToSend);
}
This previous use case simply shards the events contained in a message in many different messages, and keeps the same message id.
In my use cases, the message header usually is an integer used to identify the message and the rest of the buffer is filled with a sequence of events that could be of different types. Now, I want to modify Node so that it would manage the identifiers automatically so that the user can concentrate on the event processing, and I wondered if I could overload or replace the operator new for the specific purpose of adding header_size to the size of the allocated memory when creating a new message object in the Node class.
The overload should allow me to write something like this (.cpp)
Node::processMessage(const unique_ptr<Message>& message){
vector<Event>& events = readEvents(message);
vector<unique_ptr<Message>> messagesToSend;
for (const Event& event : events){
unique_ptr<Message> message(new Message(sizeof(Event));
writeInMessage<Event>(message, event);
messagesToSend.push_back(std::move(message));
}
sendMessages(messagesToSend);
}
The management of the header would be done by other methods called before or after processMessage().
I have already looked at
I have read a few stackoverflow questions and a bit of documentation on how replacing the operator new works, but it was always used globally or for the current class (in my case I do not wish to replace the operator in the Message class but in the Node class).
I vaguely remember there was a stackoverflow FAQ on operator overloading and new/delete operators overloading that didn't recommend modifying these operators here : What are the basic rules and idioms for operator overloading?.
Questions
For this purpose, is overloading the operator new in the Node class a good idea or at least a legitimate one ? If not, what would be the correct approach ?
If this approach is legitimate, what would it look like ? Would there be a need for the Message class to define the operator overloading as a friend method or something like that ? Also, would I need to overload the operator delete as well ?
Messageclass ? I do not wish to modify theMessageclass. Can't I increase the amount of raw memory and write more than sizeof(Event) bytes in the buffer ? Will that cause a memory leak ? - Big Ben BaggleMessageto be allocated with an extrasizeof(int)bytes whenNodecreates it? - François Andrieuxnew Message(header_size + sizeof(Event)). But if there is a way to writenew Message(sizeof(Event))without touching theMessageconstructor and reserve the same amount of memory then I'll take it. Maybeoperator newis not the way though. - Big Ben Bagglesizeof(int)more bytes without having to write it every time. But only in the code of theNodeclass. - Big Ben Baggleoperator new. You can overload the globaloperator newor the memberoperator new. The globaloperator newwill impact all uses ofnewin the current translation unit, so we can ignore that one. It won't be useful here. The other option is overloadingoperator newfor a specific class as a member operator. However, that only changes how allocating that class is done. If you overloadNode::operator newthen you only change what happens when you donew Node. You can't changeMessage::operator newfrom withinNode. - François Andrieux