惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
G
Google Developers Blog
B
Blog
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
The Cloudflare Blog
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
雷峰网
雷峰网
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
A
About on SuperTechFans
量子位
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Help Net Security
Help Net Security
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
N
News | PayPal Newsroom
AWS News Blog
AWS News Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
腾讯CDC
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker

博客园 - shootingstars

硬件相关概念 我的Function C的可变参数 C++概念网摘 Mifare 串行读取协议 韦根协议 学习C的可变参数 关于汇编程序调用各种C函数的例子 编译原理学习 关于标准库中的ptr_fun/binary_function/bind1st/bind2nd 使用python编写每日构建工具 boost::regex学习(5) - shootingstars - 博客园 boost::regex学习(4) - shootingstars - 博客园 boost::regex学习(3) boost::regex学习(2) 《世界大战》《变形金刚》观后感 boost::regex学习(1) boost::algorithm学习 五种迭代器
如何移植Java的类中的super到C++代码中
shootingstars · 2008-06-02 · via 博客园 - shootingstars

在Java中,继承类可以使用super访问基类中的数据变量

class A
{
    
int i = -1;
}


class B extends A
{
    
void printSuperI()
    
{
        System.out.println(
super.i);
    }

}

但是在C++中,貌似没有此类访问符。。。
能否在C++中访问基类中的数据呢?当然能够,最简单的方式莫过于在基类中定义Get/Set等属性函数,在继承类中使用即可。
问题是,变量太多,定义n多的Get/Set看着有些烦人。
呵呵,其实可以采用一种不是很正规的方式来直接访问基类中的数据(注意:在真实的项目中不建议使用此类方法,这个方法仅仅用于对C++二进制布局的了解+测试而已。我目前已经用vc8、gcc测试通过)
我们知道,在C++中,基类和继承类对象其实享用的同一块内存空间。即this指针所指位置。我们的所有数据都在this指针所指位置上,所有数据按照内存正向规则向上占用各自的位置。

例子代码:

class A
{
public:
    
int i,j;
    A()
    
{
        i 
= -1;
        j 
= -2;
    }


}
;

class B : public A
{
public:
    
void printSuperI()
    
{
        
// 此this指针及指向A::i的内存位置
        int superI = *(int *)(this);   
        
// 此this+4指针及指向A::j的内存位置(sizeof(int) == 4)
        
// 注意:此时必须知道C++的内存对齐方案,当然你可以通过命令要求按照自己的规则进行内存对齐。
        int superJ = *(int *)((char*)this+4);  
        printf(
"SuperI=%d, superJ=%d\n",superI,superJ);
    }

}
;

问题:一旦在基类中出现了虚拟函数,此时的this指针不再指向数据的第一个变量,而是指向vptr。
在此种情况下需要给this指针加上一个vptr的指针变量位置即可。

class A
{
public:
    
int i;
    A()
    
{
        i 
= -1;
    }

    
virtual void foo()
    
{
        printf(
"Foo\n");
    }


}
;

class B : public A
{
public:
    
void printSuperI()
    
{
        
int superI = *(int *)((char*)this+4);
        printf(
"SuperI=%d\n",superI);
    }

}
;

补充:
既然知道了vptr的位置,那我们可以直接手工打造函数地址来调用它(我只使用vc8调用通过,gcc调用报错。。。)
vc的c++虚拟指针手工调用

class A
{
public:
    
int i;
    
char *p;
    A()
    
{
        p 
= "5678";
        i 
= -1;
    }

    
virtual void foo(const char *s)
    
{
        printf(
"Foo, %s : %s\n",s, p);
    }

    
virtual void foo1(const char *s)
    
{
        printf(
"Foo1, %s\n",s);
    }


}
;

typedef 
void (A::*foo_fun)(const char *p);

class B : public A
{
public:
    
void printSuperI()
    
{
        unsigned 
int *vptr;
        
int superI = *(int *)((char*)this+4);
        printf(
"SuperI=%d\n",superI);
        vptr 
= (unsigned int *)this;
        foo_fun fun_ptr 
= *(foo_fun*)(*vptr);
        (
this->*fun_ptr)("1234");
        foo_fun fun_ptr1 
= *(foo_fun*)((*vptr)+4);
        (
this->*fun_ptr1)("abcd");
    }

}
;