您的问题是引用SomeClassBuilder &
可以解释为Builder<SomeClass> &
,但反之则不行(为此您需要动态转换)。由于Builder<T>
的方法返回Builder<T> &
,因此它实际上没有set_age
成员。这对模板没有问题,但对继承没有问题。
我看到3种解决方案:
- 始终首先使用
set_age
,而函数所应用的类型仍然是SomeClassBuilder &
。
- 重写
SomeClassBuilder
中的所有函数,以使它们执行基类中的方法,然后将*this
作为SomeClassBuilder &
返回。
- 使用CRTP,因此将模板参数
class Child
添加到基类,该参数获取继承的Child的类型,并让所有方法返回Child &
而不是{{1} },那么您必须Builder &
dynamic_cast
才能返回。然后this
应该继承自SomeClassBuilder
(需要向前声明)。
也:不要使用原始指针来拥有内存。代码中的原始Builder<T,SomeClassBuilder>
不是一个好兆头。请改用new
。
,
Builder<SomeClass>::setName
返回Builder<SomeClass>
,它肯定没有任何setAge()
方法。首先调用setAge()
时,您返回SomeClassBuilder
,并且它确实具有此方法,因此,此行为正是编译器所期望的。
要解决此问题,您可以尝试使用CRTP返回实际的SomeClassBuilder
。
基本上,您的构建器定义将更改为
template <typename T,typename Derived>
class Builder
{
//...
Derived& setName();
//...
};
,对于SomeClassBuilder
:
class SomeClassBuilder: public Builder<T,SomeClassBuilder> { ... }
,
如果您想坚持自己的设计方式,我认为除了使用CRTP之外别无选择。
更明确地说,这是一个可行的示例,可能会对您有所帮助:
#include <memory>
template <typename OBJECT_TYPE,typename CRTP_BUILDER_IMPL>
class Builder
{
public:
Builder() : _p_object(std::make_unique<OBJECT_TYPE>()){};
CRTP_BUILDER_IMPL& impl() { return static_cast<CRTP_BUILDER_IMPL&>(*this); }
CRTP_BUILDER_IMPL& setName(const char* const& name)
{
// do the job using name ...
return impl();
};
protected:
std::unique_ptr<OBJECT_TYPE> _p_object;
};
template <typename OBJECT_TYPE>
class SomeClassBuilder : public Builder<OBJECT_TYPE,SomeClassBuilder<OBJECT_TYPE>>
{
using base_type = Builder<OBJECT_TYPE,SomeClassBuilder<OBJECT_TYPE>>;
public:
SomeClassBuilder() : base_type() {}
SomeClassBuilder& setAge(int age)
{
// do the job using age ...
return *this;
}
std::unique_ptr<OBJECT_TYPE> build() { return std::move(base_type::_p_object); }
};
class SomeClass
{
using builder_type = SomeClassBuilder<SomeClass>;
public:
static builder_type builder() { return builder_type(); }
};
int main()
{
auto someClass = SomeClass::builder().setName("Name").setAge(109).build();
auto someClass_2 = SomeClass::builder().setAge(109).setName("Name").build();
}
本文链接:https://www.f2er.com/2992777.html