Builder模式实施中的类型不完整错误

时间:2018-12-25 23:19:25

标签: c++ builder

我在玩Builder模式。而且,我遇到了“返回类型不完整”的问题。什么是正确的实施方式?

// HtmlElement.h

#include <iostream>
#include <string>
using namespace std;

class HtmlBuilder;
class HtmlElement
{
  string name, text;
  HtmlElement()
    {
      cout << "HtmlElement created\n";
    }
 public:
  ~HtmlElement()
    {
      cout << "HtmlElement destroyed\n";
    }

  static HtmlBuilder create();

  friend ostream& operator<<(ostream& os, const HtmlElement& obj)
  {
    return os
      << "name: " << obj.name
      << " text: " << obj.text << endl;
  }

  friend class HtmlBuilder;

};

// HtmlBuilder.h

#include "HtmlElement.h"

using namespace std;
class HtmlBuilder
{
  HtmlElement root;
 public:
  HtmlBuilder()
    {
      root.name = "root";
      root.text = "dummy";
    }
  ~HtmlBuilder()
    {

    }
  HtmlElement build() { return root; }
};

// HtmlElement.cpp

    HtmlBuilder HtmlElement::create()
    {
      return HtmlBuilder();
    }

编译器抛出与不完整类型有关的错误。

HtmlElement.cpp:4:33: error: return type 'class HtmlBuilder' is incomplete
4 | HtmlBuilder HtmlElement::create()
  |                                 ^
HtmlElement.cpp: In static member function 'static void HtmlElement::create()':
HtmlElement.cpp:6:22: error: invalid use of incomplete type 'class HtmlBuilder'
6 |   return HtmlBuilder();
  |                      ^
In file included from HtmlElement.cpp:1:
HtmlElement.h:7:7: note: forward declaration of 'class HtmlBuilder'
7 | class HtmlBuilder;

我也试图在构建器对象中有一个指向HtmlElement类的指针。但是,仍然存在相同的错误。

1 个答案:

答案 0 :(得分:0)

您遇到了麻烦:

class HtmlElement
{
public:
    static HtmlBuilder create(); // requires complete definition of HtmlBuilder
                                 // -> include HtmlBuilder.h
};

class HtmlBuilder
{
public:
    HtmlElement build();         // requires complete definition of HtmlElement
                                 // -> include HtmlBuilder.h
};

i。 e。 HtmlElement需要包含HtmlBuilder,反之亦然,这是循环包含(由于循环类型依赖性,这是不可避免的)。

您需要通过任何合适的方法来打破这种依赖性。一种方法是让create函数返回一个指针:

HtmlBuilder* HtmlElement::create();
// possibly better a smart pointer:
std::unique_ptr<HtmlBuilder> HtmlElement::create();

但是,问题是:为什么根本需要静态创建器功能?该函数比构造函数还能做什么?如果您需要能够区分不同的构造类型,则可以通过标记类型(类似于execution policies中使用的std::for_each)来实现。