嵌套虚函数
Nested virtual functions
鉴于以下情况:
struct A
{
const float x;
const float y;
A(float x, float y)
: x{x}, y{y} {}
};
class B
{
public:
B(const float& floating)
: floating{floating} {}
virtual float foo_x() const = 0;
virtual float foo_y() const = 0;
virtual A foo() const
{
return A(foo_x(), foo_y());
}
protected:
const float& floating;
};
class C : public B
{
public:
C(const int* integer, const float& floating)
: B{floating}, integer{integer} {}
virtual float foo_x() const override
{
return static_cast<float>(*integer) + floating + 1.0f;
}
virtual float foo_y() const override
{
return static_cast<float>(*integer) - floating - 2.0f;
}
private:
const int* integer;
};
int main()
{
float F{1.0f};
int I{1};
C object(&I, F);
A res{object.foo()};
}
foo()
的定义有什么问题吗?上面的代码片段产生了预期的结果(res
持有 3
和 -2
),但是在一个更大的项目中类似的设置在调用 foo()
时产生了一些意想不到的结果,同时给出如果我从 C
分别调用 foo_x()
和 foo_y()
,则输出正确(很抱歉,我无法以最小的方式重现该错误)。
我是否通过在 B
中 foo()
的定义中调用 foo_x()
和 foo_y()
来调用一些未定义的行为?在我看来,由于 foo()
最终被 C
调用,vtable 应该被正确解析,但也许我遗漏了什么。
Am I invoking some undefined behavior by calling foo_x() and foo_y() inside the definition of foo() in B?
没有。只要满足调用虚函数的所有常规先决条件,它的定义就很好,并且可以按照您期望的方式工作。
关于这些先决条件最容易犯的错误是子类 C
在这种情况下,必须在 virtual
调用之前完全构建。
鉴于以下情况:
struct A
{
const float x;
const float y;
A(float x, float y)
: x{x}, y{y} {}
};
class B
{
public:
B(const float& floating)
: floating{floating} {}
virtual float foo_x() const = 0;
virtual float foo_y() const = 0;
virtual A foo() const
{
return A(foo_x(), foo_y());
}
protected:
const float& floating;
};
class C : public B
{
public:
C(const int* integer, const float& floating)
: B{floating}, integer{integer} {}
virtual float foo_x() const override
{
return static_cast<float>(*integer) + floating + 1.0f;
}
virtual float foo_y() const override
{
return static_cast<float>(*integer) - floating - 2.0f;
}
private:
const int* integer;
};
int main()
{
float F{1.0f};
int I{1};
C object(&I, F);
A res{object.foo()};
}
foo()
的定义有什么问题吗?上面的代码片段产生了预期的结果(res
持有 3
和 -2
),但是在一个更大的项目中类似的设置在调用 foo()
时产生了一些意想不到的结果,同时给出如果我从 C
分别调用 foo_x()
和 foo_y()
,则输出正确(很抱歉,我无法以最小的方式重现该错误)。
我是否通过在 B
中 foo()
的定义中调用 foo_x()
和 foo_y()
来调用一些未定义的行为?在我看来,由于 foo()
最终被 C
调用,vtable 应该被正确解析,但也许我遗漏了什么。
Am I invoking some undefined behavior by calling foo_x() and foo_y() inside the definition of foo() in B?
没有。只要满足调用虚函数的所有常规先决条件,它的定义就很好,并且可以按照您期望的方式工作。
关于这些先决条件最容易犯的错误是子类 C
在这种情况下,必须在 virtual
调用之前完全构建。