目录
构造函数不能声明为虚函数
在C++中,构造函数不能声明为虚函数。这是因为在执行类的构造函数时,内存中还没有虚表,也就是还没有定义虚指针。因此,构造函数必须始终是非虚的。这是C++语言设计的一部分,以确保在对象构造期间能够正确地初始化虚函数表和虚指针。因此,构造函数不能声明为虚函数。
但是,C++中可以有虚析构函数。以下是一个示例代码:
#include<iostream>
using namespace std;
class Base {
public:
Base() {
cout << "Constructing base \n";
}
virtual ~Base() {
cout << "Destructing base \n";
}
};
class Derived : public Base {
public:
Derived() {
cout << "Constructing derived \n";
}
~Derived() {
cout << "Destructing derived \n";
}
};
int main(void) {
Derived *derived = new Derived();
Base *bptr = derived;
delete bptr;
return 0;
}
输出结果为:
Constructing base
Constructing derived
Destructing derived
Destructing base
这个例子展示了虚析构函数的用法。
虚函数表是如何在C++中被初始化的?
在C++中,虚函数表(vtable)是在对象的构造期间被初始化的。虚函数表是一个存储类的虚函数指针的数组,用于实现多态性。在对象构造期间,虚函数表会被填充为指向正确的虚函数的指针。
具体来说,虚函数表是在执行类的构造函数期间被初始化的。在构造函数执行期间,会为对象分配内存并初始化虚函数表。这确保了在对象构造期间能够正确地设置虚函数表和虚指针,以便在运行时进行正确的多态调用。
以下是一个示例代码,展示了虚函数表是如何在C++中被初始化的:
#include <iostream>
using namespace std;
class Base {
public:
virtual void func() {
cout << "Base::func()" << endl;
}
};
class Derived : public Base {
public:
void func() override {
cout << "Derived::func()" << endl;
}
};
int main() {
Base* basePtr = new Derived();
basePtr->func(); // 输出 "Derived::func()"
delete basePtr;
return 0;
}
在这个示例中,Base
类和 Derived
类都有一个虚函数 func
。在 main
函数中,我们创建了一个 Derived
类的对象,并将其赋值给 Base
类的指针。当调用 basePtr->func()
时,会根据虚函数表中的指针调用 Derived::func()
,实现了多态性。
虚函数表和虚函数指针在内存中的具体存储方式是什么?
- 虚函数表(vtable)和虚函数指针在内存中的具体存储方式是这样的:虚函数表是一个指针数组,存储了该类的虚函数的地址。
- 每个类有一个虚函数表,其中存储了该类的虚函数的地址。
- 而虚函数指针是一个指向虚函数表的指针,它存储了虚函数表的地址。
- 当调用一个虚函数时,实际上是通过虚函数指针找到对应的虚函数表,再从虚函数表中找到对应的虚函数地址进行调用。
这样的设计实现了多态性,使得在运行时能够正确地调用对象的实际类型的虚函数。
标签:面试题,函数,C++,表是,函数指针,构造函数,指针 From: https://www.cnblogs.com/yubo-guan/p/17970664