I am still trying to understand how to use the Google Protocol Buffers library so I hope you will excuse my ingorance if this is off topic.
I want to wrap the Google Proto Factory such that the message types are placed in unique_ptrs so I don't have to worry about the memory management.
This is what I have:
ProtoBufFactory::ProtoBufFactory() {
Anon::Protocol_descriptor();
Auth::Protocol_descriptor();
m_factory = ::google::protobuf::MessageFactory::generated_factory();
}
//https://stackoverflow.com/questions/29960871/protobuf-message-object-creation-by-name
std::unique_ptr<::google::protobuf::Message> ProtoBufFactory::create(const ::google::protobuf::Descriptor * msg_descriptor) {
const ::google::protobuf::Message * prototype_msg = m_factory->GetPrototype( msg_descriptor );
if (prototype_msg == nullptr) {
EXCEPT(1, "Cannot create prototype message from message descriptor");
}
::google::protobuf::Message * mutable_msg = prototype_msg->New();
if (mutable_msg == NULL) {
EXCEPT(1, "Failed in prototype_msg->New(); to create mutable message");
}
return std::make_unique<::google::protobuf::Message>(mutable_msg);
}
I'm getting an error indicating that I cannot do this because I am operating on an abstract type.
error: invalid new-expression of abstract class type ‘google::protobuf::Message’
857 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
/include/google/protobuf/message.h:235:23: note: because the following virtual functions are pure within ‘google::protobuf::Message’:
235 | class PROTOBUF_EXPORT Message : public MessageLite {
| ^~~~~~~
/usr/local/include/google/protobuf/message.h:244:12: note: ‘virtual google::protobuf::Message* google::protobuf::Message::New() const’
244 | Message* New() const override = 0;
/usr/local/include/google/protobuf/message_lite.h:465:15: note: ‘virtual int google::protobuf::MessageLite::GetCachedSize() const’
465 | virtual int GetCachedSize() const = 0;
/usr/local/include/google/protobuf/message.h:367:20: note: ‘virtual google::protobuf::Metadata google::protobuf::Message::GetMetadata() const’
367 | virtual Metadata GetMetadata() const = 0;
I am confused by this error message. There is a reddit post where a similar error was reported unrelated to google protobuf: https://www.reddit.com/r/cpp_questions/comments/goa2he/stdunique_ptr_stdmake_unique_and_abstract_classes/
that seems to be because child classes were missing implementations of the abstract class. I thought it might be a linker problem but from what I can tell I'm linking the C++ protobuf generated files.
I'm not quite sure how best to proceed with this or even if unique_ptrs are all that beneficial in this circumstance.
I was hoping that there was an easy way to create a unique_ptr to the Google protocol buffer messages so I do not have to worry about explicitly deleting them.
std::make_unique
is misnamed. It should be std::emplace_unique_ptr
.
It both creates the object and allocates space for it and stores it in a smart pointer.
As you already have an object and space for it, you don't use make_unique
:
return std::unique_ptr<::google::protobuf::Message>(mutable_msg);
but instead just make a unique_ptr
wrapping the pointer.