C++ 我不明白为什么它调用 "father class static function" 而它只调用父析构函数

C++ i can`t understand why it call "father class static function" and it call just father destructor

我有下一个代码:

#include <iostream>

using namespace std;

class A{
public:
    A() { cout << "A() ";}
    virtual void f()=0;
    virtual void g() { cout << "ag() ";}
    static void h() { cout << "ah() ";}
    void i() { cout << "ai() ";}
    ~A() { cout << "~A() "; }
};

class B: public A{
    void f() { cout << "bf() ";}
public:
    void g() { cout << "bg() ";}
};

class C: public B{
public:
    static void h() { cout << "ch() "; }
    void g() { cout << "cg() ";}
    ~C() { cout << "~C() ";}
};

void f1(){
    B b;
    C c;
    b.h();
    c.h();  
    A* arr[2] = { new B ,new C};
    arr[0]->h();
    arr[1]->h();
    delete arr[0];
    delete arr[1];
}


int main(){
    f1();
    return 0;
}

我不明白为什么它打印 A() A() ah() ch() A() A() ah() ah() ~A() ~A() ~C() ~ A() ~A() 并且它不打印 A() A() ah() ch() A() A() ah() ch() ~A() ~A() ~C() ~ A()〜C()。谁能帮帮我?

这是因为 arr 是一个包含指向 A class 个实例的指针的数组。

因此,调用 arr[0]->h() 会调用 A::h()h() 不是虚拟 class 方法。您显然了解虚拟继承的工作原理以及虚拟函数如何覆盖其基础 class 版本。但是,要使虚拟继承起作用,实际上必须使用 virtual 关键字声明该函数。您没有看到用于声明 h() class 方法的 virtual 关键字,是吗,那么您为什么期望 h() 像虚函数一样工作?

其实因为h()其实是一个staticclass函数,那么

arr[0]->h();
arr[1]->h();

完全等同于:

A::h();
A::h();

编译器甚至懒得编译检索 arr[0]arr[1] 指针的代码,因为它们是不相关的。 this 不被 static class 方法使用,当然,所以没有必要浪费时间弄清楚 this 应该是什么。

首先,您忘记声明 A virtual 的析构函数。因此,通过 A 指针删除派生对象具有未定义的行为。未定义行为的一种可能结果是 ~C() 未打印(并且内存已泄漏)。一个体面的编译器会警告你这一点,除非你忘记启用警告。

解决方法:不要通过基class指针删除对象,或者将基class的析构函数设为虚

其次,调用arr[0]->h()时不会打印ch(),因为arr[0]的静态类型不是C*,而是A*。不使用虚拟分派,因为函数不是虚拟的。而且它不能是虚拟的,因为它是一个静态成员函数。不能覆盖静态成员函数。

解决方法:调整你的预期。