为其他 class 重载运算符 new
Overloading operator new for other class
用例
我有一个 Node
class 可以读取、创建 Message
object 并将其发送给其他 Node
class。我不想修改 Message
class 构造函数,因为我也在其他 class 中使用它。
Message
object基本上是这样的(Message.hpp文件)
class Message {
size_t size;
char* buffer;
Message(size_t capacity) : buffer(new char[capacity]), size(0) {}
}
一个用例可能看起来像那样(.cpp 文件)
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);
}
这个先前的用例只是将一条消息中包含的事件分成许多不同的消息,并保持相同的消息 ID。
在我的用例中,消息 header 通常是一个整数,用于标识消息,缓冲区的其余部分填充了一系列可能属于不同类型的事件。现在,我想修改 Node
使其自动管理标识符,以便用户可以专注于事件处理,我想知道是否可以重载或替换 operator new
用于特定目的在 Node
class.
中创建新消息 object 时,将 header_size
添加到已分配内存的大小
重载应该允许我写这样的东西 (.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);
}
header 的管理将通过 processMessage()
之前或之后调用的其他方法完成。
我已经看过了
我已经阅读了一些 Whosebug 问题和一些关于如何替换 operator new 的文档,但它总是全局使用或用于当前 class(在我的情况下我不希望替换Message
class 但在 Node
class).
中的运算符
我依稀记得有一个关于运算符重载和 new/delete 运算符重载的 Whosebug 常见问题解答,不建议在此处修改这些运算符:What are the basic rules and idioms for operator overloading?.
问题
为此,在 Node
class 中重载 operator new 是个好主意还是至少是合法的?如果不是,正确的方法是什么?
如果这种方法是合法的,它会是什么样子? Message
class 是否需要将运算符重载定义为友元方法或类似方法?另外,我还需要重载 operator delete
吗?
感谢 François Andrieux 及时的答复。对我的问题的简短回答是创建一个工厂模式来创建 Message
objects。像 :
(Node.cpp)
unique_ptr<Message> Node::createMessage(size_t capacity) {
return unique_ptr(new Message(capacity + header_size));
}
这样,用户就不必在每次要创建新消息时都精确 header 大小 object。这样做的缺点是用户必须知道要使用的确切方法。如果 Message
自然构造函数不可访问,则可以强制用户使用此方法。
重载 operator new
不是答案,理由如下:
There are only two options for overloading operator new
. You can overload the global operator new
or the member operator new
. The global operator new
will impact all uses of new in the current translation unit, so we can ignore that one. It won't be useful here. The other option is overloading operator new
for a specific class as a member operator. However, that only changes how allocating that class is done. If you overload Node::operator new
then you only change what happens when you do new Node
. You can't change Message::operator new
from within Node
另一种分配比自然构造函数更多 space 的可能性是使用 placement new。然而,这使得构建和破坏 over-complicated 这不是预期的 objective 。此外,让用户每次都写入 new Message(header_size + capacity)
比让他分配和释放内存的风险更小。
用例
我有一个 Node
class 可以读取、创建 Message
object 并将其发送给其他 Node
class。我不想修改 Message
class 构造函数,因为我也在其他 class 中使用它。
Message
object基本上是这样的(Message.hpp文件)
class Message { size_t size; char* buffer; Message(size_t capacity) : buffer(new char[capacity]), size(0) {} }
一个用例可能看起来像那样(.cpp 文件)
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); }
这个先前的用例只是将一条消息中包含的事件分成许多不同的消息,并保持相同的消息 ID。
在我的用例中,消息 header 通常是一个整数,用于标识消息,缓冲区的其余部分填充了一系列可能属于不同类型的事件。现在,我想修改 Node
使其自动管理标识符,以便用户可以专注于事件处理,我想知道是否可以重载或替换 operator new
用于特定目的在 Node
class.
header_size
添加到已分配内存的大小
重载应该允许我写这样的东西 (.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); }
header 的管理将通过 processMessage()
之前或之后调用的其他方法完成。
我已经看过了
我已经阅读了一些 Whosebug 问题和一些关于如何替换 operator new 的文档,但它总是全局使用或用于当前 class(在我的情况下我不希望替换Message
class 但在 Node
class).
我依稀记得有一个关于运算符重载和 new/delete 运算符重载的 Whosebug 常见问题解答,不建议在此处修改这些运算符:What are the basic rules and idioms for operator overloading?.
问题
为此,在 Node
class 中重载 operator new 是个好主意还是至少是合法的?如果不是,正确的方法是什么?
如果这种方法是合法的,它会是什么样子? Message
class 是否需要将运算符重载定义为友元方法或类似方法?另外,我还需要重载 operator delete
吗?
感谢 François Andrieux 及时的答复。对我的问题的简短回答是创建一个工厂模式来创建 Message
objects。像 :
(Node.cpp)
unique_ptr<Message> Node::createMessage(size_t capacity) { return unique_ptr(new Message(capacity + header_size)); }
这样,用户就不必在每次要创建新消息时都精确 header 大小 object。这样做的缺点是用户必须知道要使用的确切方法。如果 Message
自然构造函数不可访问,则可以强制用户使用此方法。
重载 operator new
不是答案,理由如下:
There are only two options for overloading
operator new
. You can overload the globaloperator new
or the memberoperator new
. The globaloperator new
will impact all uses of new in the current translation unit, so we can ignore that one. It won't be useful here. The other option is overloadingoperator new
for a specific class as a member operator. However, that only changes how allocating that class is done. If you overloadNode::operator new
then you only change what happens when you donew Node
. You can't changeMessage::operator new
from withinNode
另一种分配比自然构造函数更多 space 的可能性是使用 placement new。然而,这使得构建和破坏 over-complicated 这不是预期的 objective 。此外,让用户每次都写入 new Message(header_size + capacity)
比让他分配和释放内存的风险更小。