在 C++ 中,使用虚函数可以实现多态,而在构造函数中调用虚函数,可以实现基类指针指向子类对象时,子类特有的部分得到正确的初始化。但是,直接在构造函数中调用虚函数是不安全的,因为在子类还没有被构造完毕时,该函数的实现可能还没有被初始化。所以,在构造函数中调用虚函数需要采用一些特殊的技巧来保证安全。
一种有效的解决方法是,使用 “虚函数前缀” 技巧。即使用关键字 override
或加上后缀 _override
,强制使派生类的虚函数覆盖基类函数。然后,在基类的构造函数中,调用一个私有、纯虚的虚函数,由派生类重载实现。这三个条件都满足时,就可以保证在构造函数中调用虚函数的安全性。
以下是实现过程:
- 在基类中定义纯虚的虚函数。示例代码如下:
class Base {
public:
Base() {
init();
}
virtual ~Base() {}
private:
virtual void init() = 0;
};
- 在派生类中定义该虚函数的实现。示例代码如下:
class Derived : public Base {
public:
Derived() {}
private:
void init() override {
// 实现具体的初始化操作
}
};
需要注意的是,派生类的构造函数应该在基类构造函数调用之后调用,这样才能保证在基类构造函数中调用派生类的虚函数时,派生类已经被构造完毕了。
- 示例一
#include <iostream>
using namespace std;
class Base {
public:
Base() {
init();
}
virtual ~Base() {}
private:
virtual void init() = 0;
};
class Derived : public Base {
public:
Derived() {}
private:
void init() override {
cout << "Derived initialized" << endl;
}
};
int main() {
Derived d;
return 0;
}
输出结果:
Derived initialized
- 示例二
#include <iostream>
using namespace std;
class Base {
public:
Base() {
init();
}
virtual ~Base() {}
private:
virtual void init() = 0;
};
class Derived1 : public Base {
public:
Derived1() {}
private:
void init() override {
cout << "Derived1 initialized" << endl;
}
};
class Derived2 : public Base {
public:
Derived2() {}
private:
void init() override {
cout << "Derived2 initialized" << endl;
}
};
int main() {
Derived1 d1;
Derived2 d2;
return 0;
}
输出结果:
Derived1 initialized
Derived2 initialized
可以看到,在基类的构造函数中调用虚函数,在不同的派生类中执行了不同的初始化操作,实现了多态的效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++ 构造函数中调用虚函数的实现方法 - Python技术站