У меня есть суперкласс с классом, определенным в нем. лайк:
class A {
public:
class B {public: bool value;};
A() {
DoStuff(b_);
}
B b_;
private:
virtual void DoStuffImpl(B& b) = 0;
void DoStuff(B& b) { return DoStuffImpl(b); }
};
class X : public A {
// ...
private:
virtual void DoStuffImpl(B& b);
void UseBForSomethingElse(B& b);
};
void X::DoStuffImpl(B& b) {
UseBForSomethingElse(b);
}
void X::UseBForSomethingElse(B& b) {
b.value = true;
}
int main(){
X x;
return x.b_.value;
}
Мой компилятор, кажется, понимает, что DoStuffImpl()
просто хорошо. Но когда я добавил UseBForSomethingElse()
компилятор не может найти определение для B
учебный класс. Я пытался уточнить, делая bool UseBForSomethingElse(A::B& b)
, Это скомпилировано, но затем не удалось во время ссылки.
Как правильно указать родителя B
и почему она работает для виртуальной функции, а не для другой?
Ваше обновленное сообщение не соответствует требованиям UseBForSomethingElse ().
void UseBForSomethingElse(const B& b)
должно быть
void X::UseBForSomethingElse(const B& b)
Как только это будет исправлено, у вас все еще будет проблема (и, если я ошибаюсь, помогите мне, боже)
Вы запускаете виртуальный метод из конструктора базового класса без завершающей конструкции производного класса. Т.е. UseBForSomethingElse (не виртуальный) запускается из DoStuffImpl () (виртуальный, pure @ A, определенный в X) до Х закончил базовое строительство (вы, на самом деле в Базовая конструкция X, когда вы делаете вызов). Это вызовет «чисто виртуальную вызванную функцию», так как vtable X не исправлен, пока его конструктор фактически не введен.
это делает случается и на моей машине, кстати.
РЕДАКТИРОВАТЬ на основе OP редактировать:
Ideone говорит, что у вас есть ошибка во время выполнения, потому что вы возвращая 1 из основного. Любое ненулевое возвращаемое значение из main
будет считаться неудачным исполнением. Если вы просто измените возврат на return !x.b_.value;
Ideone сообщает об успехе, как и ожидалось.
Оригинальный ответ:
void UseBForSomethingElse(const B& b) {
b.value = true;
}
Вы не можете назначить постоянную ссылку (b
), так что это, безусловно, одна из ваших проблем.
Кроме того, вы не соответствовали определению UseBForSomethingElse
с X::
поэтому компилятор не помещает его в сферу X
, не давая ему видеть вложенный класс родителя.