Java与C++的构建者?

Fra*_*ank 11 c++ java design-patterns builder

在Google的Protocol Buffer API for Java中,他们使用这些创建对象的很好的构建器(参见此处):

Person john =
  Person.newBuilder()
    .setId(1234)
    .setName("John Doe")
    .setEmail("jdoe@example.com")
    .addPhone(
      Person.PhoneNumber.newBuilder()
        .setNumber("555-4321")
        .setType(Person.PhoneType.HOME))
    .build();
Run Code Online (Sandbox Code Playgroud)

但是相应的C++ API不使用这样的构建器(参见这里)

C++和Java API应该做同样的事情,所以我想知道他们为什么不在C++中使用构建器.是否有语言原因,即它不是惯用的,或者在C++中不受欢迎?或者可能只是编写C++版协议缓冲区的人的个人偏好?

hrn*_*rnt 8

在C++中实现类似的东西的正确方法将使用返回*this的引用的setter.

class Person {
  std::string name;
public:
  Person &setName(string const &s) { name = s; return *this; }
  Person &addPhone(PhoneNumber const &n);
};
Run Code Online (Sandbox Code Playgroud)

假设类似定义的PhoneNumber,可以像这样使用类:

Person p = Person()
  .setName("foo")
  .addPhone(PhoneNumber()
    .setNumber("123-4567"));
Run Code Online (Sandbox Code Playgroud)

如果需要单独的构建器类,那么也可以这样做.当然,这些构建器应该以堆栈形式分配.


Dou*_*der 0

在 C++ 中,您必须显式管理内存,这可能会使该习惯用法使用起来更加痛苦 - 要么build()必须为构建器调用析构函数,要么必须保留它以在构造对象后将其删除Person。两者对我来说都有点可怕。

  • 难道你不能通过将所有内容都保留在堆栈上来解决这个问题吗? (6认同)
  • 但事实并非如此——C++ 中的临时对象是微不足道的。它们在完整表达式结束时(即构建之后)被销毁。使用模板,创建这样的构建器将变得微不足道,因为您可以创建一个通用的构建器 - 不需要专门化。IE。`人= Builder()。(&Person::id, 1234).(&Person::Name, "John Doe");` (6认同)
  • 或使用智能指针(在某种程度上,这相当于同一件事) (4认同)