我们都知道C++多态是通过虚函数表来实现的,那具体是什么样的大家清楚吗?开篇依旧提出来几个问题:

  • 普通类对象是什么布局?
  • 带虚函数的类对象是什么布局?
  • 单继承下不含有覆盖函数的类对象是什么布局?
  • 单继承下含有覆盖函数的类对象是什么布局?
  • 多继承下不含有覆盖函数的类对象是什么布局?
  • 多继承下含有覆盖函数的类对象的是什么布局?
  • 多继承中不同的继承顺序产生的类对象布局相同吗?
  • 虚继承的类对象是什么布局?
  • 菱形继承下类对象是什么布局?
  • 为什么要引入虚继承?
  • 为什么虚函数表中有两个析构函数?
  • 为什么构造函数不能是虚函数?
  • 为什么基类析构函数需要是虚函数?

要回答上述问题我们首先需要了解什么是多态。

什么是多态

多态可以分为编译时多态和运行时多态。

  • 编译时多态:基于模板和函数重载方式,在编译时就已经确定对象的行为,也称为静态绑定。

  • 运行时多态:面向对象的一大特色,通过继承方式使得程序在运行时才会确定相应调用的方法,也称为动态绑定,它的实现主要是依赖于传说中的虚函数表。

如何查看对象的布局

在gcc中可以使用如下命令查看对象布局:

 

g++ -fdump-class-hierarchy model.cc后查看生成的文件

在clang中可以使用如下命令:

 

clang -Xclang -fdump-record-layouts -stdlib=libc++ -c model.cc
// 查看对象布局
clang -Xclang -fdump-vtable-layouts -stdlib=libc++ -c model.cc
// 查看虚函数表布局

上面两种方式其实足够了,也可以使用gdb来查看内存布局,这里可以看文末相关参考资料。本文都是使用clang来查看的对象布局。

接下来让我们一起来探秘下各种继承条件下类对象的布局情况吧~

1. 普通类对象的布局

如下代码:

 

struct Base {Base() = default;~Base() = default;void Func() {}int a;int b;
};int main() {Base a;return 0; 
}// 使用clang -Xclang -fdump-record-layouts -stdlib=libc++ -c model.cc查看

输出如下:

 

*** Dumping AST Record Layout0 | struct Base0 |   int a4 |   int b| [sizeof=8, dsize=8, align=4,|  nvsize=8, nvalign=4]*** Dumping IRgen Record Layout

画出图如下:

1.png

从结果中可以看见,这个普通结构体Base的大小为8字节,a占4个字节,b占4个字节。

2. 带虚函数的类对象的布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("FuncB\n");}int a;int b;
};int main() {Base a;return 0; 
}// 这里可以查看对象的布局和相应虚函数表的布局
clang -Xclang -fdump-record-layouts -stdlib=libc++ -c model.cc
clang -Xclang -fdump-vtable-layouts -stdlib=libc++ -c model.cc

对象布局如下:

 

*** Dumping AST Record Layout0 | struct Base0 |   (Base vtable pointer)8 |   int a12 |   int b| [sizeof=16, dsize=16, align=8,|  nvsize=16, nvalign=8]*** Dumping IRgen Record Layout

这个含有虚函数的结构体大小为16,在对象的头部,前8个字节是虚函数表的指针,指向虚函数的相应函数指针地址,a占4个字节,b占4个字节,总大小为16。

虚函数表布局:

 

Vtable for 'Base' (5 entries).0 | offset_to_top (0)1 | Base RTTI-- (Base, 0) vtable address --2 | Base::~Base() [complete]3 | Base::~Base() [deleting]4 | void Base::FuncB()

画出对象布局图如下:

2.png

我们来探秘下传说中的虚函数表:

offset_to_top(0):表示当前这个虚函数表地址距离对象顶部地址的偏移量,因为对象的头部就是虚函数表的指针,所以偏移量为0。

RTTI指针:指向存储运行时类型信息(type_info)的地址,用于运行时类型识别,用于typeid和dynamic_cast。

RTTI下面就是虚函数表指针真正指向的地址啦,存储了类里面所有的虚函数,至于这里为什么会有两个析构函数,大家可以先关注对象的布局,最下面会介绍。

3. 单继承下不含有覆盖函数的类对象的布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("Base FuncB\n");}int a;int b;
};struct Derive : public Base{
};int main() {Base a;Derive d;return 0; 
}

子类对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct Base (primary base)0 |     (Base vtable pointer)8 |     int a12 |     int b| [sizeof=16, dsize=16, align=8,|  nvsize=16, nvalign=8]*** Dumping IRgen Record Layout

和上面相同,这个含有虚函数的结构体大小为16,在对象的头部,前8个字节是虚函数表的指针,指向虚函数的相应函数指针地址,a占4个字节,b占4个字节,总大小为16。

子类虚函数表布局:

 

Vtable for 'Derive' (5 entries).0 | offset_to_top (0)1 | Derive RTTI-- (Base, 0) vtable address ---- (Derive, 0) vtable address --2 | Derive::~Derive() [complete]3 | Derive::~Derive() [deleting]4 | void Base::FuncB()

画图如下:

3.png

这个和上面也是相同的,注意下虚函数表这里的FuncB函数,还是Base类中的FuncB,因为在子类中没有重写这个函数,那么如果子类重写这个函数后对象布局是什么样的,请继续往下看哈。

4. 单继承下含有覆盖函数的类对象的布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("Base FuncB\n");}int a;int b;
};struct Derive : public Base{void FuncB() override {printf("Derive FuncB \n");}
};int main() {Base a;Derive d;return 0; 
}

子类对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct Base (primary base)0 |     (Base vtable pointer)8 |     int a12 |     int b| [sizeof=16, dsize=16, align=8,|  nvsize=16, nvalign=8]*** Dumping IRgen Record Layout

依旧和上面相同,这个含有虚函数的结构体大小为16,在对象的头部,前8个字节是虚函数表的指针,指向虚函数的相应函数指针地址,a占4个字节,b占4个字节,总大小为16。

子类虚函数表布局:

 

Vtable for 'Derive' (5 entries).0 | offset_to_top (0)1 | Derive RTTI-- (Base, 0) vtable address ---- (Derive, 0) vtable address --2 | Derive::~Derive() [complete]3 | Derive::~Derive() [deleting]4 | void Derive::FuncB()

4.png

注意这里虚函数表中的FuncB函数已经是Derive中的FuncB啦,因为在子类中重写了父类的这个函数。

再注意这里的RTTI中有了两项,表示Base和Derive的虚表地址是相同的,Base类里的虚函数和Derive类里的虚函数都在这个链条下,这里可以继续关注下面多继承的情况,看看有何不同。

5. 多继承下不含有覆盖函数的类对象的布局

 

struct BaseA {BaseA() = default;virtual ~BaseA() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct BaseB {BaseB() = default;virtual ~BaseB() = default;void FuncA() {}virtual void FuncC() {printf("BaseB FuncC\n");}int a;int b;
};struct Derive : public BaseA, public BaseB{
};int main() {BaseA a;Derive d;return 0; 
}

类对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct BaseA (primary base)0 |     (BaseA vtable pointer)8 |     int a12 |     int b16 |   struct BaseB (base)16 |     (BaseB vtable pointer)24 |     int a28 |     int b| [sizeof=32, dsize=32, align=8,|  nvsize=32, nvalign=8]

Derive大小为32,注意这里有了两个虚表指针,因为Derive是多继承,一般情况下继承了几个带有虚函数的类,对象布局中就有几个虚表指针,并且子类也会继承基类的数据,一般来说,不考虑内存对齐的话,子类(继承父类)的大小=子类(不继承父类)的大小+所有父类的大小

虚函数表布局:

 

Vtable for 'Derive' (10 entries).0 | offset_to_top (0)1 | Derive RTTI-- (BaseA, 0) vtable address ---- (Derive, 0) vtable address --2 | Derive::~Derive() [complete]3 | Derive::~Derive() [deleting]4 | void BaseA::FuncB()5 | offset_to_top (-16)6 | Derive RTTI-- (BaseB, 16) vtable address --7 | Derive::~Derive() [complete][this adjustment: -16 non-virtual]8 | Derive::~Derive() [deleting][this adjustment: -16 non-virtual]9 | void BaseB::FuncC()

可画出对象布局图如下:

5.png

offset_to_top(0):表示当前这个虚函数表(BaseA,Derive)地址距离对象顶部地址的偏移量,因为对象的头部就是虚函数表的指针,所以偏移量为0。

再注意这里的RTTI中有了两项,表示BaseA和Derive的虚表地址是相同的,BaseA类里的虚函数和Derive类里的虚函数都在这个链条下,截至到offset_to_top(-16)之前都是BaseA和Derive的虚函数表。

offset_to_top(-16):表示当前这个虚函数表(BaseB)地址距离对象顶部地址的偏移量,因为对象的头部就是虚函数表的指针,所以偏移量为-16,这里用于this指针偏移,下一小节会介绍。

注意下后面的这个RTTI:只有一项,表示BaseB的虚函数表,后面也有两个虚析构函数,为什么有四个Derive类的析构函数呢,又是怎么调用呢,请继续往下看~

6. 多继承下含有覆盖函数的类对象的布局

 

struct BaseA {BaseA() = default;virtual ~BaseA() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct BaseB {BaseB() = default;virtual ~BaseB() = default;void FuncA() {}virtual void FuncC() {printf("BaseB FuncC\n");}int a;int b;
};struct Derive : public BaseA, public BaseB{void FuncB() override {printf("Derive FuncB \n");}void FuncC() override {printf("Derive FuncC \n");}
};int main() {BaseA a;Derive d;return 0; 
}

对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct BaseA (primary base)0 |     (BaseA vtable pointer)8 |     int a12 |     int b16 |   struct BaseB (base)16 |     (BaseB vtable pointer)24 |     int a28 |     int b| [sizeof=32, dsize=32, align=8,|  nvsize=32, nvalign=8]*** Dumping IRgen Record Layout

类大小仍然是32,和上面一样。

虚函数表布局:

 

Vtable for 'Derive' (11 entries).0 | offset_to_top (0)1 | Derive RTTI-- (BaseA, 0) vtable address ---- (Derive, 0) vtable address --2 | Derive::~Derive() [complete]3 | Derive::~Derive() [deleting]4 | void Derive::FuncB()5 | void Derive::FuncC()6 | offset_to_top (-16)7 | Derive RTTI-- (BaseB, 16) vtable address --8 | Derive::~Derive() [complete][this adjustment: -16 non-virtual]9 | Derive::~Derive() [deleting][this adjustment: -16 non-virtual]10 | void Derive::FuncC()[this adjustment: -16 non-virtual]

6.png

offset_to_top(0):表示当前这个虚函数表(BaseA,Derive)地址距离对象顶部地址的偏移量,因为对象的头部就是虚函数表的指针,所以偏移量为0。

再注意这里的RTTI中有了两项,表示BaseA和Derive的虚表地址是相同的,BaseA类里的虚函数和Derive类里的虚函数都在这个链条下,截至到offset_to_top(-16)之前都是BaseA和Derive的虚函数表。

offset_to_top(-16):表示当前这个虚函数表(BaseB)地址距离对象顶部地址的偏移量,因为对象的头部就是虚函数表的指针,所以偏移量为-16。当基类BaseB的引用或指针base实际接受的是Derive类型的对象,执行base->FuncC()时候,由于FuncC()已经被重写,而此时的this指针指向的是BaseB类型的对象,需要对this指针进行调整,就是offset_to_top(-16),所以this指针向上调整了16字节,之后调用FuncC(),就调用到了被重写后Derive虚函数表中的FuncC()函数。这些带adjustment标记的函数都是需要进行指针调整的。至于上面所说的这里虚函数是怎么调用的,估计您也明白了吧~

7. 多重继承不同的继承顺序导致的类对象的布局相同吗?

 

struct BaseA {BaseA() = default;virtual ~BaseA() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct BaseB {BaseB() = default;virtual ~BaseB() = default;void FuncA() {}virtual void FuncC() {printf("BaseB FuncC\n");}int a;int b;
};struct Derive : public BaseB, public BaseA{void FuncB() override {printf("Derive FuncB \n");}void FuncC() override {printf("Derive FuncC \n");}
};int main() {BaseA a;Derive d;return 0; 
}

对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct BaseB (primary base)0 |     (BaseB vtable pointer)8 |     int a12 |     int b16 |   struct BaseA (base)16 |     (BaseA vtable pointer)24 |     int a28 |     int b| [sizeof=32, dsize=32, align=8,|  nvsize=32, nvalign=8]*** Dumping IRgen Record Layout

这里可见,对象布局和上面的不相同啦,BaseB的虚函数表指针和数据在上面,BaseA的虚函数表指针和数据在下面,以A,B的顺序继承,对象的布局就是A在上B在下,以B,A的顺序继承,对象的布局就是B在上A在下。

虚函数表布局:

 

Vtable for 'Derive' (11 entries).0 | offset_to_top (0)1 | Derive RTTI-- (BaseB, 0) vtable address ---- (Derive, 0) vtable address --2 | Derive::~Derive() [complete]3 | Derive::~Derive() [deleting]4 | void Derive::FuncC()5 | void Derive::FuncB()6 | offset_to_top (-16)7 | Derive RTTI-- (BaseA, 16) vtable address --8 | Derive::~Derive() [complete][this adjustment: -16 non-virtual]9 | Derive::~Derive() [deleting][this adjustment: -16 non-virtual]10 | void Derive::FuncB()[this adjustment: -16 non-virtual]

对象布局图如下:

7.png

虚函数表的布局也有所不同,BaseB和Derive共用一个虚表地址,在整个虚表布局的上方,而布局的下半部分是BaseA的虚表,可见继承顺序不同,子类的虚表布局也有所不同。

8. 虚继承的布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct Derive : virtual public Base{void FuncB() override {printf("Derive FuncB \n");}
};int main() {Base a;Derive d;return 0; 
}

对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   (Derive vtable pointer)8 |   struct Base (virtual base)8 |     (Base vtable pointer)16 |     int a20 |     int b| [sizeof=24, dsize=24, align=8,|  nvsize=8, nvalign=8]*** Dumping IRgen Record Layout

虚继承下,这里的对象布局和普通单继承有所不同,普通单继承下子类和基类共用一个虚表地址,而在虚继承下,子类和虚基类分别有一个虚表地址的指针,两个指针大小总和为16,再加上a和b的大小8,为24。

虚函数表:

 

Vtable for 'Derive' (13 entries).0 | vbase_offset (8)1 | offset_to_top (0)2 | Derive RTTI-- (Derive, 0) vtable address --3 | void Derive::FuncB()4 | Derive::~Derive() [complete]5 | Derive::~Derive() [deleting]6 | vcall_offset (-8)7 | vcall_offset (-8)8 | offset_to_top (-8)9 | Derive RTTI-- (Base, 8) vtable address --10 | Derive::~Derive() [complete][this adjustment: 0 non-virtual, -24 vcall offset offset]11 | Derive::~Derive() [deleting][this adjustment: 0 non-virtual, -24 vcall offset offset]12 | void Derive::FuncB()[this adjustment: 0 non-virtual, -32 vcall offset offset]

对象布局图如下:

8.png

vbase_offset(8):对象在对象布局中与指向虚基类虚函数表的指针地址的偏移量

vcall_offset(-8):当虚基类Base的引用或指针base实际接受的是Derive类型的对象,执行base->FuncB()时候,由于FuncB()已经被重写,而此时的this指针指向的是Base类型的对象,需要对this指针进行调整,就是vcall_offset(-8),所以this指针向上调整了8字节,之后调用FuncB(),就调用到了被重写后的FuncB()函数。

9. 虚继承带未覆盖函数的对象布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("Base FuncB\n");}virtual void FuncC() {printf("Base FuncC\n");}int a;int b;
};struct Derive : virtual public Base{void FuncB() override {printf("Derive FuncB \n");}
};int main() {Base a;Derive d;return 0; 
}

对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   (Derive vtable pointer)8 |   struct Base (virtual base)8 |     (Base vtable pointer)16 |     int a20 |     int b| [sizeof=24, dsize=24, align=8,|  nvsize=8, nvalign=8]*** Dumping IRgen Record Layout

和上面虚继承情况下相同,普通单继承下子类和基类共用一个虚表地址,而在虚继承下,子类和虚基类分别有一个虚表地址的指针,两个指针大小总和为16,再加上a和b的大小8,为24。

虚函数表布局:

 

Vtable for 'Derive' (15 entries).0 | vbase_offset (8)1 | offset_to_top (0)2 | Derive RTTI-- (Derive, 0) vtable address --3 | void Derive::FuncB()4 | Derive::~Derive() [complete]5 | Derive::~Derive() [deleting]6 | vcall_offset (0)7 | vcall_offset (-8)8 | vcall_offset (-8)9 | offset_to_top (-8)10 | Derive RTTI-- (Base, 8) vtable address --11 | Derive::~Derive() [complete][this adjustment: 0 non-virtual, -24 vcall offset offset]12 | Derive::~Derive() [deleting][this adjustment: 0 non-virtual, -24 vcall offset offset]13 | void Derive::FuncB()[this adjustment: 0 non-virtual, -32 vcall offset offset]14 | void Base::FuncC()

对象布局图如下:

9.png

vbase_offset(8):对象在对象布局中与指向虚基类虚函数表的指针地址的偏移量

vcall_offset(-8):当虚基类Base的引用或指针base实际接受的是Derive类型的对象,执行base->FuncB()时候,由于FuncB()已经被重写,而此时的this指针指向的是Base类型的对象,需要对this指针进行调整,就是vcall_offset(-8),所以this指针向上调整了8字节,之后调用FuncB(),就调用到了被重写后的FuncB()函数。

vcall_offset(0):当Base的引用或指针base实际接受的是Derive类型的对象,执行base->FuncC()时候,由于FuncC()没有被重写,所以不需要对this指针进行调整,就是vcall_offset(0),之后调用FuncC()。

10. 菱形继承下类对象的布局

 

struct Base {Base() = default;virtual ~Base() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct BaseA : virtual public Base {BaseA() = default;virtual ~BaseA() = default;void FuncA() {}virtual void FuncB() {printf("BaseA FuncB\n");}int a;int b;
};struct BaseB : virtual public Base {BaseB() = default;virtual ~BaseB() = default;void FuncA() {}virtual void FuncC() {printf("BaseB FuncC\n");}int a;int b;
};struct Derive : public BaseB, public BaseA{void FuncB() override {printf("Derive FuncB \n");}void FuncC() override {printf("Derive FuncC \n");}
};int main() {BaseA a;Derive d;return 0; 
}

类对象布局:

 

*** Dumping AST Record Layout0 | struct Derive0 |   struct BaseB (primary base)0 |     (BaseB vtable pointer)8 |     int a12 |     int b16 |   struct BaseA (base)16 |     (BaseA vtable pointer)24 |     int a28 |     int b32 |   struct Base (virtual base)32 |     (Base vtable pointer)40 |     int a44 |     int b| [sizeof=48, dsize=48, align=8,|  nvsize=32, nvalign=8]*** Dumping IRgen Record Layout

大小为48,这里不用做过多介绍啦,相信您已经知道了吧。

虚函数表:

 

Vtable for 'Derive' (20 entries).0 | vbase_offset (32)1 | offset_to_top (0)2 | Derive RTTI-- (BaseB, 0) vtable address ---- (Derive, 0) vtable address --3 | Derive::~Derive() [complete]4 | Derive::~Derive() [deleting]5 | void Derive::FuncC()6 | void Derive::FuncB()7 | vbase_offset (16)8 | offset_to_top (-16)9 | Derive RTTI-- (BaseA, 16) vtable address --10 | Derive::~Derive() [complete][this adjustment: -16 non-virtual]11 | Derive::~Derive() [deleting][this adjustment: -16 non-virtual]12 | void Derive::FuncB()[this adjustment: -16 non-virtual]13 | vcall_offset (-32)14 | vcall_offset (-32)15 | offset_to_top (-32)16 | Derive RTTI-- (Base, 32) vtable address --17 | Derive::~Derive() [complete][this adjustment: 0 non-virtual, -24 vcall offset offset]18 | Derive::~Derive() [deleting][this adjustment: 0 non-virtual, -24 vcall offset offset]19 | void Derive::FuncB()[this adjustment: 0 non-virtual, -32 vcall offset offset]

对象布局图如下:

10.png

vbase_offset (32)

vbase_offset (16):对象在对象布局中与指向虚基类虚函数表的指针地址的偏移量

offset_to_top (0)

offset_to_top (-16)

offset_to_top (-32):指向虚函数表的地址与对象顶部地址的偏移量。

vcall_offset(-32):当虚基类Base的引用或指针base实际接受的是Derive类型的对象,执行base->FuncB()时候,由于FuncB()已经被重写,而此时的this指针指向的是Base类型的对象,需要对this指针进行调整,就是vcall_offset(-32),所以this指针向上调整了32字节,之后调用FuncB(),就调用到了被重写后的FuncB()函数。

为什么要虚继承

如图:

11.png

非虚继承时,显然D会继承两次A,内部就会存储两份A的数据浪费空间,而且还有二义性,D调用A的方法时,由于有两个A,究竟时调用哪个A的方法呢,编译器也不知道,就会报错,所以有了虚继承,解决了空间浪费以及二义性问题。在虚拟继承下,只有一个共享的基类子对象被继承,而无论该基类在派生层次中出现多少次。共享的基类子对象被称为虚基类。在虚继承下,基类子对象的复制及由此而引起的二义性都被消除了。

为什么虚函数表中有两个析构函数

前面的代码输出中我们可以看到虚函数表中有两个析构函数,一个标志为deleting,一个标志为complete,因为对象有两种构造方式,栈构造和堆构造,所以对应的实现上,对象也有两种析构方式,其中堆上对象的析构和栈上对象的析构不同之处在于,栈内存的析构不需要执行 delete 函数,会自动被回收。

为什么构造函数不能是虚函数。

构造函数就是为了在编译阶段确定对象的类型以及为对象分配空间,如果类中有虚函数,那就会在构造函数中初始化虚函数表,虚函数的执行却需要依赖虚函数表。如果构造函数是虚函数,那它就需要依赖虚函数表才可执行,而只有在构造函数中才会初始化虚函数表,鸡生蛋蛋生鸡的问题,很矛盾,所以构造函数不能是虚函数。

为什么基类析构函数要是虚函数。

一般基类的析构函数都要设置成虚函数,因为如果不设置成虚函数,在析构的过程中只会调用到基类的析构函数而不会调用到子类的析构函数,可能会产生内存泄漏。

小总结

offset_to_top:对象在对象布局中与对象顶部地址的偏移量。

RTTI指针:指向存储运行时类型信息(type_info)的地址,用于运行时类型识别,用于typeid和dynamic_cast。

vbase_offset:对象在对象布局中与指向虚基类虚函数表的指针地址的偏移量。

vcall_offset:父类引用或指针指向子类对象,调用被子类重写的方法时,用于对虚函数执行指针地址调整,方便成功调用被重写的方法。

thunk: 表示上面虚函数表中带有adjustment字段的函数调用需要先进行this指针调整,才可以调用到被子类重写的函数。

最后通过两张图总结一下对象在Linux中的布局:

 

A *a = new Derive(); // A为Derive的基类

如图:

12.png

a作为对象指针存储在栈中,指向在堆中的类A的实例内存,其中实例内存布局中有虚函数表指针,指针指向的虚函数表存放在数据段中,虚函数表中的各个函数指针指向的函数在代码段中。

13.png

虚表结构大体如上图,正常的虚表结构中都含有后三项,当有虚继承情况下会有前两个表项。

参考资料:

https://www.cnblogs.com/qg-whz/p/4909359.html

https://blog.csdn.net/fuzhongmin05/article/details/59112081

https://zhuanlan.zhihu.com/p/67177829

https://mp.weixin.qq.com/s/sqpwQpPYBFkPWCmccruvNw

https://jacktang816.github.io/post/virtualfunction/

https://blog.mengy.org/cpp-virtual-table-2/

https://blog.mengy.org/cpp-virtual-table-1/

https://blog.mengy.org/extend-gdb-with-python/

https://www.zhihu.com/question/389546003/answer/1194780618

https://www.zhihu.com/question/29251261/answer/1297439131

https://zhuanlan.zhihu.com/p/41309205

https://wizardforcel.gitbooks.io/100-gdb-tips/examine-memory.html

https://www.cnblogs.com/xhb19960928/p/11720314.html

https://www.lagou.com/lgeduarticle/113008.html



查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. JavaScript:18-ES6语法、let、const、var、解构赋值、箭头函数、剩余参数、ES6的内置对象扩展、Array的扩展方法、String的扩展方法、Set数据结构、模板字符串

    文章目录ES6语法目标ES6相关概念(★★)什么是ES6为什么使用 ES6 ?ES6新增语法let(★★★)let声明的变量只在所处于的块级有效不存在变量提升暂时性死区经典面试题小结const(★★★)具有块级作用域声明常量时必须赋值常量赋值后,值不能修改小结let、const、var 的区别解…...

    2024/5/10 6:09:42
  2. SpringBoot+Vue下载Excel文件流(No converter、Excel乱码)

    目录介绍No converterExcel乱码正确代码后端代码前端代码 介绍 后端使用SpringBoot、Mybatis Plus,前端使用Vue,进行Excel文件下载。 后端使用了Hutool工具提供的Excel文件流下载。 No converter 问题: 后端控制台出现No converter for [class com.common.lang.Result] with…...

    2024/4/29 22:09:47
  3. 论文:Baby Steps Towards Few-Shot Learning with Multiple Semantics

    1、Baby Steps Towards Few-Shot Learning with Multiple Semantics 目的:记录下对文章的理解 摘要:额外的语义信息可以显著提高少样本学习的能力,论文在少样本学习中结合了多种丰富的语义,这里语义信息包括类别标签、属性和自然语言描述等信息。论文在miniImageNet 和CUB …...

    2024/4/29 22:09:42
  4. C++基础--复合类型

    复合类型是指基于其他类型定义的类型,C++有几种复合类型,本章主要介绍引用和指针。 1.引用 引用为对象起了另一个名字,引用类型引用另外一种类型。通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量。 int i=1024; int &iref = i;//iref是i的引用 int &am…...

    2024/4/29 22:09:38
  5. putty和xshell远程连接虚拟机

    使用putty软件ssh服务器 下载地址:https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html打开putty软件在Host Name 的文本框中输入对应主机ip地址,比如我的Centos7服务器地址为192.168.111.137; 端口号默认是22,登录模式默认是SSH;如果有需求用telnet的 需要在…...

    2024/5/10 5:18:09
  6. 一张图读懂 Vue 生命周期

    英文版:中文版:感谢B站博主的分享。...

    2024/4/29 22:09:35
  7. ES6之Symbol

    JavaScript 原本有六种数据类型,分别是undefined、null、Boolean、String、Number、Object。ES6 引入了一种新的原始数据类型Symbol,它表示独一无二的值。 Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象,也不能添加属性。 …...

    2024/4/29 0:58:07
  8. Java知识点汇总以及常见面试题

    Java知识点汇总以及常见面试题“==”和equals()的区别 ==比较基本数据类型,比较的是值是否相等,比较引用数据类型时是地址值是否相等,地址值相等代表引用同一个对象,返回true。 equals(),在Object类中比较的是地址值是否相等,而在其他类重写后,根据重写的equals()方法进…...

    2024/5/8 12:46:08
  9. 小甲鱼 -------------------tkinter : ListBox组件

    背景:设计一个选择框,里面的选择有很多很多。 比如设计一个省份,城市的选择框 from tkinter import *master = Tk()theLB = Listbox(master) theLB.pack()for item in ["北京", "上海", "广州", "成都"]:END 是每次都插入在表的最后…...

    2024/4/29 22:09:22
  10. 机器学习—隐马尔科夫模型HMM

    本文简单的对HMM做一下笔记。 概率图模型:是一种以图(Graph)为表示的工具,来表达变量间相关关系的概率模型。在概率图模型中,一个节点表示一个随机变量或者一组随机变量,而节点之间的边则表示变量之间概率的相关关系。边可以是有向的,也可以是无向的。概率模型大致分为:…...

    2024/4/29 22:09:18
  11. Inductive Matrix Completion Based on Graph Neural Networks

    参考文献Inductive Matrix Completion Based on Graph Neural Networks - ICLR 2020〇、相关工作 1、Graph Neural Network 图神经网络(GNNs)是一种用于在图形上学习的新型神经网络。主要分为两种类型:Node Level GNNs和Graph Level GNNs。Nodelevel GNNs使用消息传递层在每个…...

    2024/4/29 22:09:13
  12. 计划七天-----学习JavaScript核心DOM BOM操作(界面交互功能)-----第六天

    ②删除事件 1.传统注册事件 eventTarget.οnclick=null; 2.方法监听注册事件 eventTarget.removeEventListener(type,listener[,useCapture]); <style>div{width:100px;height:100px;background-color:pink;} </style> <body><div>1</div><di…...

    2024/4/29 22:09:11
  13. Java 面试题_JavaWeb 部分

    申明:本资源收集于互联网,仅供参考,文中如存在错误,欢迎交流指正 面试题_JavaWeb 部分申明:本资源收集于互联网,仅供参考,文中如存在错误,欢迎交流指正1、四种会话跟踪技术2、Jsp 九大隐式对象3、Servlet 的生命周期4、Servlet 和 Jsp 的关系5、什么是 MVC?6、重定向(…...

    2024/4/29 22:09:06
  14. 面部口罩识别检测

    面部口罩识别检测@人脸识别 项目介绍 【 项目背景:随着新冠疫情的爆发,公共卫生防护程度被提高到空前状态。为防止新冠病毒的交叉传染,导致疫情扩散,人们在各大公共场所活动时均被要求佩戴口罩。因此,面部口罩检测项目诞生。 项目前景:随着公共卫生防护程度的逐步提升,且…...

    2024/4/29 22:09:03
  15. 华为云计算——FusionSphere OpenStack单节点部署

    介绍 FusionSphere是华为公司面向多行业客户推出的云操作系统产品,基于OpenStack架构开发,是华为基于社区原生OpenStack开发的商用版OpenStack。整个系统专门为云设计和优化,提供强大的虚拟化功能和资源池管理、丰富的云基础服务组件和工具、开放的API接口等。其具有Opensta…...

    2024/4/29 22:08:59
  16. Hashtable 和 ConcurrentHashMap 的详细讲解

    在多线程的环境下HashMap是线程不安全的,那么我们该如何处理这样的情况? 通常有三种方式:使用Collections.synchronizedMap(Map)创建线程安全的map集合 使用Hashtable 使用ConcurrentHashMap类不过由于前两个并发度的原因,通常会选择第三个,它的效率和性能明显要比前两个高…...

    2024/4/29 22:08:53
  17. Vue双向绑定

    实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点: 1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监…...

    2024/5/9 14:01:02
  18. 定点整数,定点小数,浮点数

    定/浮点数的表示是为了解决小数点问题,而定点数的编码则是为了解决正负号的问题。今天来记录一下定点和浮点数的表示。定点小数用来表示浮点数的尾数,定点整数用来表示浮点数的阶,即指数,需要注意的是,定点小数用原码来表示,定点整数用移码来表示,(带符号整数是用补码来…...

    2024/4/29 22:08:47
  19. 电子邮件(email)服务器与DNS系统的联系

    电子邮件(email)服务器与DNS域名解析系统是分不开的,假如你需要发电子邮件,需要通过邮件(email)服务器帮你将信件送出去。总所周知,IP地址相对难以记忆,如果把难记的ip地址变成域名地址,就会好得多,通过域名ip的映射,这就是DNS系统,因此在收发电子邮件的过程中要用到DN…...

    2024/4/29 22:08:43
  20. Java基础----选择语句(switch...case)

    格式:switch(表达式) {case 常量值1:语句体1;break;case 常量值2:语句体2;break;...default:语句体n+1;break; }123456789101112 执行流程: 首先计算出表达式的值 其次,和 case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。 最后,如…...

    2024/4/29 22:08:38

最新文章

  1. 卡码网模拟笔试题第十六期 |

    A、构造二阶行列式 数字不大&#xff0c;直接四重循环暴力枚举 #include <iostream> using namespace std;int main() {int x;cin >> x;for (int i 1; i < 20; i) {for (int j 1; j < 20;j) {for (int x1 1;x1 < 20;x1) {for (int y 1;y<20;y){if…...

    2024/5/10 6:34:20
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/9 21:23:04
  3. composer常见错误解决

    在Java中&#xff0c;常见的问题和解决方法包括&#xff1a; 内存不足错误&#xff1a;Java应用程序在运行时可能会遇到内存不足的错误。可以通过增加JVM的堆内存大小来解决&#xff0c;可以通过设置-Xms和-Xmx参数来指定初始堆大小和最大堆大小。 java -Xms2G -Xmx4G YourAppl…...

    2024/5/5 8:38:08
  4. 汽车疲劳测试试验平台技术要求(北重厂家)

    汽车疲劳测试试验平台技术要求通常包括以下几个方面&#xff1a; 车辆加载能力&#xff1a;测试平台需要具备足够的承载能力&#xff0c;能够同时测试多种车型和不同重量的车辆。 动力系统&#xff1a;测试平台需要具备稳定可靠的动力系统&#xff0c;能够提供足够的力和速度来…...

    2024/5/10 0:22:17
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/10 1:36:26
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/9 7:40:42
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/9 2:44:26
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/10 2:07:45
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/9 3:15:57
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/9 5:40:03
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/9 7:40:40
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/10 2:07:43
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/10 2:07:43
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/9 4:12:16
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/9 7:40:35
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/9 19:47:07
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/9 7:40:34
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/10 2:07:41
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/9 5:02:59
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/9 4:31:45
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/9 16:54:42
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/10 1:31:37
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/9 6:36:49
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/9 4:33:29
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57