약간 특이한 문제가 발생했습니다. 다음 코드를 고려하십시오데이터 멤버의 수명을 한 메서드로 제한
class parser
{
lexer lex;
public:
node_ptr parse(const std::string& expression)
{
lex.init(expression.begin(), expression.end());
// ...
// call some helper methods
// return the result
}
private:
// lots of small helper methods, many of them accessing lex
};
구문 분석 방법은 init
방법으로 렉서를 초기화합니다. 그 전에 렉서는 사용할 수없는 "기본"상태입니다. 일반적으로, 하나는 건설 기간 동안 멤버를 초기화하기한다, 왜 나는 단순히이 작업을 수행하지 않습니다
class parser
{
lexer lex;
public:
parser(const std::string& expr) : lex(expr.begin(), expr.end()) {}
node_ptr parse()
{
// call some helper methods
// return the result
}
// ...
};
첫째, 이것은 클라이언트가 구문 분석 방법 훨씬 이해가되지 것 여러 번 호출 할 수 있음을 의미합니다.
둘째, 더 중요한 것은 아주 쉽게 될 수 있습니다 심각한 수명 문제 : 위의 코드에서
parser my_parser("1 * 2 + 3 * 4");
auto root = my_parser.parse();
는 렉서는 말에 존재 중단 임시 문자열 객체로 초기화됩니다 그렇기 때문에 다음 줄에 parse
메서드를 호출하면 정의되지 않은 동작이 호출됩니다.
이러한 두 가지 이유로 저는 같은 방법으로 초기화하고 구문 분석하려고합니다. 불행히도 결과를 반환해야하고 생성자가 결과를 반환 할 수 없기 때문에 생성자에서이 작업을 수행 할 수 없습니다.
기술적으로는 나는 또한 생성자 따라 소멸자 변경하면 parse
방법 내부 렉서를 구성하고 나중에 그것을 파괴 할 수 있습니다 :
class parser
{
static std::string dummy;
lexer lex;
public:
parser() : lex(dummy.begin(), dummy.end())
{
lex.~lexer();
}
node_ptr parse(const std::string& expression)
{
new(&lex) lexer(expression.begin(), expression.end());
// call some helper methods
lex.~lexer();
// return the result
}
~parser()
{
new(&lex) lexer(dummy.begin(), dummy.end());
}
// ...
};
을하지만 이것은 지금까지 내가 작성했던 추한 코드 매우 긴 시간. 예외도 아닙니다. 도우미 메서드가 throw되면 어떻게됩니까? 실제로 구문 분석 오류가 발생하면 그 일이 발생합니다.
그럼이 문제를 어떻게 해결해야합니까? parse
안에있는 로컬 렉서를 사용하고 lexer*
회원 포인트가 있습니까? boost::optional<lexer>
회원을 사용 하시겠습니까? 아니면 방금 init
방법으로 살아야합니까? 또는 결국 생성자에서 구문 분석을 수행하고 원하는 결과가 포함 된 "expection"을 throw해야합니까?
호기심에서 벗어나, 거기에 무엇을 구축하고 있습니까? :) –
범위가 단일 메서드 인 경우 왜 멤버로 유지하려고합니까? –
@David 코드 주석에 쓴 것처럼 작은 헬퍼 메소드가 많이 있으며 그 중 많은 수가 렉스에 액세스합니다. – fredoverflow