我有以下类层次结构:
class Base { // This class cannot be modified
public:
Base(int a, int b, int c) {
if ( a == 100 && b == 200 && c < 100 ) // whatever condition
throw "Error!";
}
};
class Derived : public Base { // this class can be modified
public:
Derived(int a, int b, int c) : Base(a, b, c) {}
};
class Derived 在代码中的许多地方使用,因此不能用某种工厂函数替换它。
现在的问题是,是否有一些结构允许我在调用 Base 构造函数之前修复 A,B,C 值?
我知道我可以使用以下功能:
Derived(int a, int b, int c) : Base(FixA(a), FixB(b), FixC(c)) {}
int FixA(int a) { /*fix a value*/ return a; }
int FixB(int b) { /*fix b value*/ return b; }
int FixC(int c) { /*fix c value*/ return c; }
但是,如果 b c 值依赖于上面的基类 c-tor 示例,则不允许我设置正确的值。
我正在考虑将其扩展到:
Derived(int a, int b, int c) : Base(FixA(a,b,c), FixB(a,b,c), FixC(a,b,c)) {}
int FixA(int a, int& b, int& c) { /*fix a b c values*/ return a; }
int FixB(int& a, int b, int& c) { /*fix a b c values*/ return b; }
int FixC(int& a, int& b, int c) { /*fix a b c values*/ return c; }
我想还应该有某种标志表明修复已经完成。我不确定这是否真的是正确的 c++。
我知道最好的解决方案是实际捕获异常。
Derived
和 Base
之间插入一个类:
class Derived: public UnpackToBase {
public:
Derived(int a, int b, int c): UnpackToBase(FixParameters(a, b, c))
class UnpackToBase: public Base {
public:
UnpackToBase(FixParameters params): Base(params.a, params.b, params.c)
struct FixParameters {
int a, b, c;
FixParameters(int a, int b, int c): a(a), b(b), c(c) {
// do stuff
}
在 C++11 中,您可以使用 Derived
的委托构造函数:
class Derived: public Base {
public:
Derived(int a, int b, int c): Derived(FixParameters(a, b, c)) { }
Derived(FixParameters params): Base(params.a, params.b, params.c) { }
您可以使用单一实例模式来解决此问题。请参阅下面的代码。在这里,构造初始化列表的初始化顺序无关紧要。但是,我怀疑这是否可以称为优雅。
class Base
{
// This class cannot be modified
public: Base(int a, int b, int c)
{
if ( a == 100 && b == 200 && c < 100 ) // whatever condition
throw "Error!";
}
};
class Validator
{
public:
static Validator& instance(int a_in, int b_in, int c_in)
{
static Validator v(a_in,b_in,c_in);
return v;
}
int& a(){ return m_a;}
int& b(){ return m_b;}
int& c(){ return m_c;}
private:
Validator(int a_in, int b_in, int c_in) : m_a(a_in), m_b(b_in), m_c(c_in)
{
// perform validation and modify the members
// Example validation
if(m_a > 0 && m_b > 0)
{
m_c = 0;
}
}
int m_a;
int m_b;
int m_c;
};
class Derived : public Base
{
// this class can be modified
public:
Derived(int a, int b, int c) : Base(Validator::instance(a, b, c).a(), Validator::instance(a, b, c).b(), Validator::instance(a, b, c).c())
{}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derived d(1,2,3);
return 0;
}
一些奇怪的事情,所以为什么不使用好的'ol宏。
#define FIX_ME(x) //do something
Derived(int a, int b, int c) : Base(FIX_ME(a), FIX_ME(b), FIX_ME(c)) {}