我在玩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类的指针。但是,仍然存在相同的错误。
答案 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)来实现。