我有一个超类,里面定义了一个类。像:
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
,为什么它适用于虚拟功能但不适用于其他功能?
答案 0 :(得分:1)
基于OP编辑的编辑:
ideone说你有运行时错误的原因是因为你从主返回1。来自main
的任何非零返回值都将被视为执行失败。如果您只是按预期更改返回return !x.b_.value;
ideone报告成功。
原始答案:
void UseBForSomethingElse(const B& b) {
b.value = true;
}
你不能分配到一个常量引用(b
),所以这肯定是你的一个问题。
此外,您没有使用UseBForSomethingElse
限定X::
的定义,因此编译器不会将其置于X
的范围内,从而阻止它看到父级的嵌套类
答案 1 :(得分:1)
您更新的帖子未正确限定UseBForSomethingElse()。
void UseBForSomethingElse(const B& b)
应该是
void X::UseBForSomethingElse(const B& b)
一旦修复了,你仍然有问题(如果我弄错了,天堂会帮助我)。
您正在从基类构造函数触发虚方法,而不使用派生类完成构造。即,UseBForSomethingElse(非虚拟)是从DoStuffImpl()(虚拟,纯@A,在X中定义)在 X完成基础构造之前触发的(实际上是 in 拨打电话时X的基础构造。这将触发一个'纯虚函数',因为在实际输入构造函数之前,X的vtable没有被修复。
这个确实也发生在我的机器上,顺便说一下。