我决定使用builder模式来避免使用长的无命名参数构造函数,但是我有一个特定的用例。我有一个基类和一些继承自它的类,它们都必须能够分别构造。下面显示的伪代码解释了我的特殊用例:
class B
{
int i;
int j;
public:
B& setI(int i) {this->i=i; return *this;}
B& setJ(int j) {this->j=j; return *this;}
}
class I : public B
{
int i2;
int j2;
public:
I& setI2(int i) {this->i2=i; return *this;}
I& setJ2(int j) {this->j2=j; return *this;}
}
B b = B().setI(12).setJ(13); // ok
I i = I().setI(12).setJ(13).setI2(14).setJ2(15); // error the first and second function return B not I
由于B中的函数未返回类I的类型,因此无法编译以上代码。this post中提出了一种解决方案,但该解决方案是有限的,无法创建基类分别。 我正在使用c ++ 11,但可以使用其他版本的c ++。
更新:
有一种解决方案可以接受B作为I的构造函数的参数,但是在实际问题中,存在一些继承层,使用该解决方案不是很实用。
答案 0 :(得分:0)
我们可以为类Builder
使用一个I
,它最终将分配类I
及其基类B
的属性。 Builder
应该是类I
的朋友,以便我们可以访问Builder
的受保护成员,并且还要确保Builder
所有可用的属性
考虑类B
:
class B {
protected:
int first;
int second;
public:
int get_first() { return this->first; }
int get_second() { return this->second; }
};
并且,类I
:
class I : public B {
int third;
int fourth;
public:
int get_third() { return this->third; }
int get_fourth() { return this->fourth; }
class Builder : public B {
int third;
int fourth;
public:
Builder &set_first(const int &first) {
this->first = first;
return *this;
}
Builder &set_second(const int &second) {
this->second = second;
return *this;
}
Builder &set_third(const int &third) {
this->third = third;
return *this;
}
Builder &set_fourth(const int &fourth) {
this->fourth = fourth;
return *this;
}
friend class I;
};
I(const Builder &builder);
};
因此,它允许我们为属性分配值:
I::I(const I::Builder &builder) {
this->first = builder.first;
this->second = builder.second;
this->third = builder.third;
this->fourth = builder.fourth;
}
示例
int main() {
I::Builder builder;
I i = builder.set_first(100).set_second(102);
std::cout << "[sample 1] first: " << i.get_first() << "\n";
std::cout << "[sample 1] second: " << i.get_second() << "\n";
std::cout << "[sample 1] third: " << i.get_third() << "\n";
std::cout << "[sample 1] fourth: " << i.get_fourth() << "\n";
std::cout << "\n";
i = builder.set_first(12).set_second(13).set_third(14).set_fourth(15);
std::cout << "[sample 2] first: " << i.get_first() << "\n";
std::cout << "[sample 2] second: " << i.get_second() << "\n";
std::cout << "[sample 2] third: " << i.get_third() << "\n";
std::cout << "[sample 2] fourth: " << i.get_fourth() << "\n";
std::cout << "\n";
i = builder.set_first(1).set_third(3);
std::cout << "[sample 3] first: " << i.get_first() << "\n";
std::cout << "[sample 3] second: " << i.get_second() << "\n";
std::cout << "[sample 3] third: " << i.get_third() << "\n";
std::cout << "[sample 3] fourth: " << i.get_fourth() << "\n";
return 0;
}
它产生以下输出:
[sample 1] first: 100
[sample 1] second: 102
[sample 1] third: 0
[sample 1] fourth: 0
[sample 2] first: 12
[sample 2] second: 13
[sample 2] third: 14
[sample 2] fourth: 15
[sample 3] first: 1
[sample 3] second: 13
[sample 3] third: 3
[sample 3] fourth: 15