Sfoglia il codice sorgente

feat: 添加 虚继承 + 虚函数 内存布局

NiceTry12138 5 mesi fa
parent
commit
afe95613c4
1 ha cambiato i file con 64 aggiunte e 0 eliminazioni
  1. 64 0
      cpp/现代C++/现代C++.md

+ 64 - 0
cpp/现代C++/现代C++.md

@@ -367,6 +367,70 @@ int main()
 
 > Base实例被放在整个对象末尾,通过指针偏移访问
 
+如果此时再加上一个虚函数呢?
+
+这种情况下,虚函数表的指针就不一定在对象的首地址了
+
+```cpp
+#include <iostream>
+
+class Base {
+    public:
+        virtual void foo() { std::cout << "hello" << std::endl; }
+    public:
+		int x = 1;
+};
+class A : public virtual Base {
+    public:
+		int XX = 2;
+};
+class B : public virtual Base {
+    public:
+		int YY = 3;
+};
+class C : public A, public B {
+    public:
+		int ZZ = 4;
+};
+
+typedef void(*fun)(C* a);
+
+int main() {
+    std::cout << "sizeof(Base) " << sizeof(Base) << std::endl;
+    std::cout << "sizeof(A) " << sizeof(A) << std::endl;
+    std::cout << "sizeof(B) " << sizeof(B) << std::endl;
+    std::cout << "sizeof(C) " << sizeof(C) << std::endl;
+
+    std::cout << "offsetof ZZ " << offsetof(C, ZZ) << std::endl;
+
+    C* c = new C();
+    
+    for(int i = 0; i < sizeof(C); i += 4)
+    {
+        std::cout << "i = " << i << " value = " << *(int*)((char*)c + i) << std::endl;
+    }
+    /*
+    | 虚基类指针(8字节) | XX(4字节) | 占位(4字节) |
+    | 虚基类指针(8字节) | YY(4字节) | ZZ  (4字节) |
+    | 虚函数指针(8字节) | x (4字节) | 占位(4字节) |
+    */
+    
+    fun f0 = (fun)(*(long*)*(long*)c);
+    fun f1 = (fun)(*(long*)*(long*)(((char*)c + 16)));
+    fun f2 = (fun)(*(long*)*(long*)(((char*)c + 32)));
+    // f0(c);
+    // f1(c);
+    f2(c);
+    
+    std::cout << "XX = " << *(int*)((char*)c + sizeof(void*)) << std::endl;
+    std::cout << "YY = " << *(int*)((char*)c + sizeof(void*) * 2 + sizeof(int) * 2) << std::endl;
+    std::cout << "x = " << *(int*)((char*)c + sizeof(void*) * 3 + sizeof(int) * 4) << std::endl;
+    std::cout << "ZZ = " << *(int*)((char*)c + sizeof(void*) * 2 + sizeof(int) * 3) << std::endl;
+
+    return 0;
+}
+```
+
 ### 空类的内存模型
 
 ```cpp