为什么在运行时需要虚拟表来调用虚函数?

时间:2018-03-05 15:34:26

标签: c++ polymorphism virtual-functions virtual-table

我正在关注this tutorial,尝试了解import os import sys import json from PySide import QtGui, QtCore class MegaMergeWindow(QtGui.QMainWindow): def __init__(self, *args, **kwargs): super(MegaMergeWindow, self).__init__(*args, **kwargs) self.TITLE = 'Mega Merge' self.VERSION = '1.0.0' self.setWindowTitle(self.TITLE + ' | ' + self.VERSION) self.resize(350,500) # vars self.user_folder = os.path.join(os.getenv('LOCALAPPDATA'), 'MegaMerge') # controls self.ui_files = QtGui.QListView() self.ui_files.setModel(QtGui.QStandardItemModel()) self.ui_files.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.ui_merge = QtGui.QPushButton('Merge') main_layout = QtGui.QVBoxLayout() main_layout.addWidget(self.ui_files) main_layout.addWidget(self.ui_merge) main_widget = QtGui.QWidget() main_widget.setLayout(main_layout) self.setCentralWidget(main_widget) # signals self.ui_merge.clicked.connect(self.merge_clicked) self.populate_files() def populate_files(self, files=[], clear=False): model = self.ui_files.model() if clear: model.clear() files = ['Doug','Kevin','Amy','Melissa','John'] for f in files: name = os.path.basename(f) item = QtGui.QStandardItem(name) item.setData(f, role=QtCore.Qt.UserRole) item.setCheckable(True) item.setCheckState(QtCore.Qt.Checked) model.appendRow(item) model.sort(0, QtCore.Qt.AscendingOrder) def collect_paths(self): files = [] model = self.ui_files.model() for index in range(model.rowCount()): item = model.item(index) if item.checkState() == QtCore.Qt.Checked: files.append(item.text()) return files def merge_files(self, files=[]): print files def merge_clicked(self): files = self.collect_paths() print files def main(): app = QtGui.QApplication(sys.argv) ex = MegaMergeWindow() ex.show() sys.exit(app.exec_()) if __name__ == '__main__': main() 以及virtual tablepointer背后的整个过程。

不确定,当我有这样的代码时:

virtual functions in C++

为什么我需要所有这些D1 d1; Base *dPtr = &d1; dPtr->function1(); 管理?为什么编译器根本不指定virtual table的内存地址(或者如果没有任何内容,则为基数){?1}}?

我的意思是:如果它需要D1 d1地址或virtual function地址,它可以在编译时详细说明。它当时知道。为什么以后在运行时看functon1()

会浪费时间和资源

我想念这一点。花哨的例子?

1 个答案:

答案 0 :(得分:5)

这是我的功能:

void foo(Base *pBase) {
  pBase->function1();
}

我单独编译它并给你一个带标题的目标文件。甚至在梦想D1之前的几个月。编译器如何“直接使用D1的function1的地址”

它不能。这就是为什么需要某种形式的间接的原因。

除此之外,虚拟功能表不是必需,因为每个C ++实现都会使用一个。它只是当今编译器采用的最流行的实现技术。