Скажем, у меня есть 3 класса со следующей топологией, и реальный код выглядит примерно так:
// formal system.h
#pragma once
namespace nianyi {
class Proposition {
public:
class Term;
class Expression;
// Term::Value evaluate();
};
class Proposition::Term : public Proposition {
public:
class Variable;
class Value;
};
class Proposition::Term::Value : public Proposition::Term {
};
};
Легко видеть, что если я раскомментирую это объявление функции, компилятор будет жаловаться на неопределенный ранее класс Value, и это действительно так:
error C2027: use of undefined type 'nianyi::Proposition::Term'
Но с другой стороны, класс Term
происходит от его базового класса Proposition
Это означает, что я не могу поставить его реализацию в базовый класс, поскольку он не является полным классом до завершения реализации, и неполный класс не может быть получен из.
Таким образом, поставив реализацию класса Term
оба внутри & вне класса Proposition
приведет к ошибке компилятора. Внутренний вызван неполнотой базового класса, а внешний — неполнотой производной.
Итак … как лучше это решить?
Постскриптум пожалуйста, прекратите говорить «вы должны завершить определение перед использованием класса» или «просто не делайте их вложенными».
Для первых слов, вот и вся проблема, просто сказать, что это не очень помогает;
и что касается второго рода слов, я просто хотел сделать их вложенными, чтобы не раскрывать эти детали.
Это должно работать, не ясно, если это то, что вы хотите, хотя
class Proposition {
public:
};
class Term : public Proposition {
public:
class Variable {};
class Value {};
};
class Value : public Term {
};
Вот абстрактное решение.
Нет необходимости в наследстве.
class Variable{
};
class Value{
};
class Term{
class Variable;
class Value;
};
class Expression{
class Variable;
class Value;
};
class Proposition{
class Expression;
class Term;
};
Кажется, никто не обращает внимания на пункт в вашем вопросе, который говорит о возвращении «дважды вложенного класса внутри себя».
В последнее время я видел, как это делается, делая личный (или публичный, если хотите) член класса и указатель экземпляра класса. Таким образом, вы можете генерировать и возвращать указатель на класс для этого члена.
// formal system.h
#pragma once
namespace nianyi {
class Proposition {
public:
class Term;
class Expression;
// Term::Value evaluate();
Proposition( )
{
Proposition *pinstance;
prop_ = pinstance;
}
private:
Proposition *prop_;
};
class Proposition::Term : public Proposition {
public:
class Variable;
class Value;
};
class Proposition::Term::Value : public Proposition::Term {
};
};