在 C++ vs Java 中从构造函数调用被覆盖的方法
calling overridden methods from constructor in C++ vs Java
从
构造函数调用被覆盖的方法在java和C++中有所不同。有人可以解释为什么他们的调度方法有何不同吗?
我知道C++和Java的设计和演变方式不同。但是,当涉及到从构造函数调用可重写的方法时,任何关于为什么语言规范被有意设计为这种方式的见解都会有所帮助。
我进行这项调查的动机是容易出错的检查:http://errorprone.info/bugpattern/ConstructorInvokesOverridable
这是返回 1 的 java 代码
class Ideone
{
static class Simple {
public int i;
Simple() {
this.i = func();
}
public int func() {
return 2;
}
}
static class Complex extends Simple {
@Override
public int func() {
return 1;
}
}
public static void main (String[] args) throws java.lang.Exception
{
Complex c = new Complex();
System.out.println(c.i);
}
}
这是返回 2 的 c++ 代码
#include <iostream>
using namespace std;
class Simple {
public:
Simple(int i) { i_ = func(); }
virtual int func() { return 2; }
int i_;
};
class Complex : public Simple {
public:
Complex(int i) : Simple(i) {}
int func() override { return 1; }
};
int main() {
// your code goes here
Complex complex(2);
printf("Val is : %dn", complex.i_);
return 0;
}
在构造函数或析构函数中调用虚函数表示当前对象的构造/销毁状态。由于基在实际类之前初始化,因此在基类构造函数中调用它将被调度到基类函数。
派生类成员此时尚未初始化,因此派生类施加的任何不变性尚未建立。因此,派生类函数可能无法正确执行其工作。
请记住,基类首先按声明顺序初始化;然后是数据成员,按声明顺序初始化;然后构造函数运行。只有这样,对象才完成。
在ctor 和 dtor 中调用动态调度函数通常被认为是不好的做法。
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 如何使基类从子类调用覆盖函数
- 在 C++ vs Java 中从构造函数调用被覆盖的方法
- C 从同一基本模板类覆盖功能,具有多个继承模棱两可的函数调用
- C++ 调用覆盖函数会导致调用基函数
- 调用函数将覆盖值
- 未调用覆盖的虚拟函数
- C++未调用覆盖的虚拟函数
- 调用覆盖函数库