C++ 非确定性操作的设计模式(非特定工厂?)
假设我有一个重复出现的代码块:C++ 非确定性操作的设计模式(非特定工厂?),c++,design-patterns,C++,Design Patterns,假设我有一个重复出现的代码块: Class1 c1; try { c1.parse(x); } catch(Exception& e) { Class2 c2; try { c2.parse(x); } catch(Exception& e) { Class3 c3; try { // ... } // ... } } 显然,我感兴趣的
Class1 c1;
try {
c1.parse(x);
} catch(Exception& e) {
Class2 c2;
try {
c2.parse(x);
} catch(Exception& e) {
Class3 c3;
try {
// ...
}
// ...
}
}
显然,我感兴趣的是第一个类#
(#=1,2,3,…)实例,解析不会对其抛出异常
或者,Class1
,…,ClassN
有一个公共超类,我可以使用它作为返回类型
考虑到此操作会在代码中重复多次,什么是抽象此操作的简明方法
可以使用STL和Boost,不可以使用C++11,因为项目要求:(
宏是灰色区域。您可以使用类似于工厂的方法和类似于
ParserPtr CreateParser(unsinged level)
{
switch(level)
{
case 0:
return ParserPtr(new Class0);
//...
}
return nullptr;
}
然后像这样重写你的方法
void Parse()
{
unsined errorLevel = 0;
while(auto p = CreateParser(errorLevel))
{
try
{
p->parse(); /*...*/
//deallocate if ParserPtr is not shared_ptr or other smart ptr
return;
}
catch(Exception & e)
{
++errorLevel;
/*Extra exception handling, deallocating p if needed*/
}
}
//Handle case, when no parser succeeded
}
您可以使用类似工厂的方法和类似
ParserPtr CreateParser(unsinged level)
{
switch(level)
{
case 0:
return ParserPtr(new Class0);
//...
}
return nullptr;
}
然后像这样重写你的方法
void Parse()
{
unsined errorLevel = 0;
while(auto p = CreateParser(errorLevel))
{
try
{
p->parse(); /*...*/
//deallocate if ParserPtr is not shared_ptr or other smart ptr
return;
}
catch(Exception & e)
{
++errorLevel;
/*Extra exception handling, deallocating p if needed*/
}
}
//Handle case, when no parser succeeded
}
由于没有变量,并且仅限于c++03,我们不得不按照boost库的方式进行操作-前面有很多样板文件,以换取以后方便的表达式:
#include <string>
#include <stdexcept>
struct Class1 { void parse(const std::string&); };
struct Class2 { void parse(const std::string&); };
struct Class3 { void parse(const std::string&); };
struct none_type {};
template<class C>
struct try_impl
{
try_impl(int index)
: _index(index)
{
}
void apply(int& which, C& c, const std::string& s) const
{
if (which >= 0)
return;
try {
c.parse(s);
which = _index;
}
catch(...) {
// logging here?
}
}
int _index;
};
template<>
struct try_impl<none_type>
{
try_impl(int index)
: _index(index)
{
}
void apply(int& which, none_type& c, const std::string& s) const
{
}
int _index;
};
// attempt to parse all given objects. Return the index of the first one that
// passed
// return -1 if non parse correctly
//
template<class C1, class C2 = none_type, class C3 = none_type, class C4 = none_type, class C5 = none_type>
struct parse_attempt_impl
{
static int apply(const std::string& s,C1 c1, C2 c2 = C2(), C3 c3 = C3(), C4 c4 = C4(), C5 c5 = C5())
{
int which = -1;
try_impl<C1>(0).apply(which, c1, s);
try_impl<C2>(1).apply(which, c2, s);
try_impl<C3>(2).apply(which, c3, s);
try_impl<C4>(3).apply(which, c4, s);
try_impl<C5>(4).apply(which, c5, s);
return which;
}
};
// you will need to make as many of these as you need
template<class C1, class C2, class C3>
int parse_attempt(const std::string& s, C1 c1, C2 c2, C3 c3)
{
return parse_attempt_impl<C1, C2, C3>::apply(s, c1, c2, c3);
}
template<class C1, class C2, class C3, class C4>
int parse_attempt(const std::string& s, C1 c1, C2 c2, C3 c3, C4 c4)
{
return parse_attempt_impl<C1, C2, C3, C4>::apply(s, c1, c2, c3, c4);
}
int main(int argc, char**argv)
{
std::string x(argv[1]);
int which = parse_attempt(x, Class1(), Class2(), Class3());
}
#包括
#包括
结构类1{void parse(const std::string&);};
结构类2{void parse(const std::string&);};
结构类3{void parse(const std::string&);};
结构none_类型{};
模板
结构try\u impl
{
try_impl(整数索引)
:(索引)
{
}
void apply(int&which、C&C、const std::string&s)const
{
如果(哪个>=0)
返回;
试一试{
c、 解析(s);
which=_指数;
}
捕获(…){
//在这里登录?
}
}
int_指数;
};
模板
结构try\u impl
{
try_impl(整数索引)
:(索引)
{
}
void apply(int&which,none_type&c,const std::string&s)const
{
}
int_指数;
};
//尝试分析所有给定对象。返回第一个指定对象的索引
//通过
//如果未正确解析,则返回-1
//
模板
结构解析\u尝试\u执行
{
静态int应用(常量std::string&s,c1c1,c2c2=C2(),c3c3=C3(),c4c4=C4(),c5c5=C5())
{
int其中=-1;
try_impl(0).apply(哪一个,c1,s);
试着执行(1)。应用(哪一个,c2,s);
尝试应用(2),应用(哪一个,c3,s);
尝试应用(3),应用(哪一个,c4,s);
尝试实施(4)。应用(哪种,c5,s);
返回哪个;
}
};
//你将需要尽可能多的这些你需要
模板
int解析_尝试(常量std::string&s,c1c1,c2c2,c3c3)
{
返回parse_trument_impl::apply(s、c1、c2、c3);
}
模板
int解析_尝试(常量std::string&s、c1c1、c2c2、c3c3、c4c4)
{
返回parse_trument_impl::apply(s、c1、c2、c3、c4);
}
int main(int argc,字符**argv)
{
std::字符串x(argv[1]);
int=parse_尝试(x,Class1(),Class2(),Class3());
}
没有变量,并且仅限于c++03,我们被迫按照boost库的方式进行操作-前面有很多样板文件,以换取以后方便的表达:
#include <string>
#include <stdexcept>
struct Class1 { void parse(const std::string&); };
struct Class2 { void parse(const std::string&); };
struct Class3 { void parse(const std::string&); };
struct none_type {};
template<class C>
struct try_impl
{
try_impl(int index)
: _index(index)
{
}
void apply(int& which, C& c, const std::string& s) const
{
if (which >= 0)
return;
try {
c.parse(s);
which = _index;
}
catch(...) {
// logging here?
}
}
int _index;
};
template<>
struct try_impl<none_type>
{
try_impl(int index)
: _index(index)
{
}
void apply(int& which, none_type& c, const std::string& s) const
{
}
int _index;
};
// attempt to parse all given objects. Return the index of the first one that
// passed
// return -1 if non parse correctly
//
template<class C1, class C2 = none_type, class C3 = none_type, class C4 = none_type, class C5 = none_type>
struct parse_attempt_impl
{
static int apply(const std::string& s,C1 c1, C2 c2 = C2(), C3 c3 = C3(), C4 c4 = C4(), C5 c5 = C5())
{
int which = -1;
try_impl<C1>(0).apply(which, c1, s);
try_impl<C2>(1).apply(which, c2, s);
try_impl<C3>(2).apply(which, c3, s);
try_impl<C4>(3).apply(which, c4, s);
try_impl<C5>(4).apply(which, c5, s);
return which;
}
};
// you will need to make as many of these as you need
template<class C1, class C2, class C3>
int parse_attempt(const std::string& s, C1 c1, C2 c2, C3 c3)
{
return parse_attempt_impl<C1, C2, C3>::apply(s, c1, c2, c3);
}
template<class C1, class C2, class C3, class C4>
int parse_attempt(const std::string& s, C1 c1, C2 c2, C3 c3, C4 c4)
{
return parse_attempt_impl<C1, C2, C3, C4>::apply(s, c1, c2, c3, c4);
}
int main(int argc, char**argv)
{
std::string x(argv[1]);
int which = parse_attempt(x, Class1(), Class2(), Class3());
}
#包括
#包括
结构类1{void parse(const std::string&);};
结构类2{void parse(const std::string&);};
结构类3{void parse(const std::string&);};
结构none_类型{};
模板
结构try\u impl
{
try_impl(整数索引)
:(索引)
{
}
void apply(int&which、C&C、const std::string&s)const
{
如果(哪个>=0)
返回;
试一试{
c、 解析(s);
which=_指数;
}
捕获(…){
//在这里登录?
}
}
int_指数;
};
模板
结构try\u impl
{
try_impl(整数索引)
:(索引)
{
}
void apply(int&which,none_type&c,const std::string&s)const
{
}
int_指数;
};
//尝试分析所有给定对象。返回第一个指定对象的索引
//通过
//如果未正确解析,则返回-1
//
模板
结构解析\u尝试\u执行
{
静态int应用(常量std::string&s,c1c1,c2c2=C2(),c3c3=C3(),c4c4=C4(),c5c5=C5())
{
int其中=-1;
try_impl(0).apply(哪一个,c1,s);
试着执行(1)。应用(哪一个,c2,s);
尝试应用(2),应用(哪一个,c3,s);
尝试应用(3),应用(哪一个,c4,s);
尝试实施(4)。应用(哪种,c5,s);
返回哪个;
}
};
//你将需要尽可能多的这些你需要
模板
int解析_尝试(常量std::string&s,c1c1,c2c2,c3c3)
{
返回parse_trument_impl::apply(s、c1、c2、c3);
}
模板
int解析_尝试(常量std::string&s、c1c1、c2c2、c3c3、c4c4)
{
返回parse_trument_impl::apply(s、c1、c2、c3、c4);
}
int main(int argc,字符**argv)
{
std::字符串x(argv[1]);
int=parse_尝试(x,Class1(),Class2(),Class3());
}
请不要这样做。这会造成伤害。请使用返回std::optional(即在类t中:static std::optional Create(…)的“命名构造函数”,并将内部构造函数设置为私有/受保护。如果确实必须(或使用无法更改的库),请执行以下操作:
#包括
#包括
结构解析返回{};
模板
结构分析器
{
ParseReturn解析(const std::string&)
{
return ParseReturn();
}
};
模板
类解析优先
{
公众:
静态解析返回解析(const std::string&s)
{
尝试
{
返回P().parse;
}
捕获(…)
{
返回ParseFirst::parse(s);
}
}
};
模板
类解析优先
{
公众:
静态解析返回解析(const std::string&s)
{
尝试
{
返回P().parse;
}
捕获(…)
{
//也许再扔一次?
}
}
};
int main(){
std::字符串s;
ParseFirst::解析;
返回0;
}
请不要这样做。这会造成伤害。请使用返回std::optional(即在类t中:static std::optional Create(…)的“命名构造函数”,并将内部构造函数设置为私有/受保护。如果确实必须(或使用无法更改的库),请执行以下操作:
#包括
#包括
结构解析返回{};
模板
结构分析器
{
ParseReturn解析(const std::string&)
{
return ParseReturn();
}
};
模板
类解析优先
{
酒吧