我想在重新解释的类中从父类函数调用子类函数,如下所示。
#include <iostream>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class An");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class Bn");
}
};
int main() {
A* ab = new A();
ab->func1(); // this print "class A"
B* bab = reinterpret_cast<B*>(ab);
bab->func1(); // this also print "class A"
// I want to print "class B" when I use bab->func1()
}
在这种情况下,有没有办法使用重新解释的类bab
而不重新定义func1
来打印类B ?
要使c++多态性发挥作用,必须在某处创建派生类的实例,但是可以存储指向基类的指针。使用基类指针将分派到派生类的重写函数。所以你对A
和B
的定义是正确的,你在主函数中的用法就不正确了。reinterpret_cast
不是用来做这个的
#include <iostream>
#include <memory>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class An");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class Bn");
}
};
int main() {
{
// This works, but don't do this. Naked "new" is not modern C++ and dangerous.
A* ab = new B();
ab->func1();
delete ab;
}
{
// VARIANT 2: use smart pointers
std::unique_ptr<A> ab = std::make_unique<B>();
ab->func1();
}
{
// VARIANT 3: A non-smart pointer is okay, as long as it
// 1. references an existing allocated object
// 2. the pointer does not outlive the object it points to
B b;
A* ab = &b;
ab->func1();
}
{
// VARIANT 4: Like Variant 3, but with reference instead of pointer
B b;
A& ab = b;
ab.func1();
}
}
输出class B
class B
class B
class B
https://godbolt.org/z/8e5E85nx5
编辑:尽量避免使用new
分配。以这种方式分配的任何内存都必须由您使用delete
释放,并且很容易忘记(我第一次写这个答案时就忘记了,这有点证明了我的观点)。即使你在函数结束时删除了内存,也有可能你的代码永远不会达到这个语句,例如,如果在new
和delete
之间的某个地方抛出异常。- 为什么使用'new'是个坏主意? 为什么c++程序员应该尽量减少'new'的使用?