support bazel complie this project and format code.

This commit is contained in:
zhangxing
2023-03-30 00:15:11 +08:00
committed by light-city
parent 1f86192576
commit 7529ae3a55
636 changed files with 10025 additions and 9387 deletions

View File

@@ -0,0 +1,8 @@
# please run `bazel run basic_content/vptr_vtable:vptr1`
load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "vptr1",
srcs = ["vptr1.cpp"],
copts = ["-std=c++11"]
)

View File

@@ -1,12 +1,3 @@
/**
* @file vptr1.cpp
* @brief C++虚函数vptr和vtable
* 编译g++ -g -o vptr vptr1.cpp -std=c++11
* @author 光城
* @version v1
* @date 2019-07-20
*/
#include <iostream>
#include <stdio.h>
using namespace std;
@@ -16,90 +7,75 @@ using namespace std;
*/
typedef void (*Fun)();
/**
* @brief 基类
*/
class Base
{
public:
Base(){};
virtual void fun1()
{
cout << "Base::fun1()" << endl;
}
virtual void fun2()
{
cout << "Base::fun2()" << endl;
}
virtual void fun3(){}
~Base(){};
class Base {
public:
Base(){};
virtual void fun1() { cout << "Base::fun1()" << endl; }
virtual void fun2() { cout << "Base::fun2()" << endl; }
virtual void fun3() {}
~Base(){};
};
/**
* @brief 派生类
*/
class Derived: public Base
{
public:
Derived(){};
void fun1()
{
cout << "Derived::fun1()" << endl;
}
void fun2()
{
cout << "DerivedClass::fun2()" << endl;
}
~Derived(){};
class Derived : public Base {
public:
Derived(){};
void fun1() { cout << "Derived::fun1()" << endl; }
void fun2() { cout << "DerivedClass::fun2()" << endl; }
~Derived(){};
};
/**
* @brief 获取vptr地址与func地址,vptr指向的是一块内存这块内存存放的是虚函数地址这块内存就是我们所说的虚表
* @brief
* 获取vptr地址与func地址,vptr指向的是一块内存这块内存存放的是虚函数地址这块内存就是我们所说的虚表
*
* @param obj
* @param offset
*
* @return
* @return
*/
Fun getAddr(void* obj,unsigned int offset)
{
cout<<"======================="<<endl;
void* vptr_addr = (void *)*(unsigned long *)obj; //64位操作系统占8字节通过*(unsigned long *)obj取出前8字节即vptr指针
printf("vptr_addr:%p\n",vptr_addr);
Fun getAddr(void *obj, unsigned int offset) {
cout << "=======================" << endl;
void *vptr_addr =
(void *)*(unsigned long *)obj; // 64位操作系统占8字节通过*(unsigned
// long *)obj取出前8字节即vptr指针
printf("vptr_addr:%p\n", vptr_addr);
/**
* @brief 通过vptr指针访问virtual table因为虚表中每个元素(虚函数指针)在64位编译器下是8个字节因此通过*(unsigned long *)vptr_addr取出前8字节
* 后面加上偏移量就是每个函数的地址!
*/
void* func_addr = (void *)*((unsigned long *)vptr_addr+offset);
printf("func_addr:%p\n",func_addr);
return (Fun)func_addr;
/**
* @brief 通过vptr指针访问virtual
* table因为虚表中每个元素(虚函数指针)在64位编译器下是8个字节因此通过*(unsigned
* long *)vptr_addr取出前8字节 后面加上偏移量就是每个函数的地址!
*/
void *func_addr = (void *)*((unsigned long *)vptr_addr + offset);
printf("func_addr:%p\n", func_addr);
return (Fun)func_addr;
}
int main(void)
{
Base ptr;
Derived d;
Base *pt = new Derived(); // 基类指针指向派生类实例
Base &pp = ptr; // 基类引用指向类实例
Base &p = d; // 基类引用指向派生类实例
cout<<"基类对象直接调用"<<endl;
ptr.fun1();
cout<<"基类引用指向基类实例"<<endl;
pp.fun1();
cout<<"基类指针指向派生类实例并调用虚函数"<<endl;
pt->fun1();
cout<<"基类引用指向派生类实例并调用虚函数"<<endl;
p.fun1();
int main(void) {
Base ptr;
Derived d;
Base *pt = new Derived(); // 基类指针指向派生类实例
Base &pp = ptr; // 基类引用指向基类实例
Base &p = d; // 基类引用指向派生类实例
cout << "基类对象直接调用" << endl;
ptr.fun1();
cout << "基类引用指向基类实例" << endl;
pp.fun1();
cout << "基类指针指向派生类实例并调用虚函数" << endl;
pt->fun1();
cout << "基类引用指向派生类实例并调用虚函数" << endl;
p.fun1();
// 手动查找vptr 和 vtable
Fun f1 = getAddr(pt, 0);
(*f1)();
Fun f2 = getAddr(pt, 1);
(*f2)();
// 手动查找vptr 和 vtable
Fun f1 = getAddr(pt, 0);
(*f1)();
Fun f2 = getAddr(pt, 1);
(*f2)();
delete pt;
return 0;
delete pt;
return 0;
}