C++类函数深入理解

C++函数与类的深入理解 本文详细探讨了C++中函数的参数传递、原型声明、内联函数、重载以及类和对象的概念。通过代码示例和错误分析,文章揭示了C++编程中函数和类的高级特性及其应用。 阅读详情

最近在做Android 播放器的项目,native 需要用到C++,遇到一个有意思的问题,先mark下。

先看一段代码:

class A
{
public:
    int v;
    
public:
    A():v(0){}
    void print() const
    {
        printf("%s enter. this=%p\n", __func__, this);
    }
};

int main(int argc, const char * argv[])
{
    A* a = NULL;
    A* a1 = new A();
    A a2;
    
    //printf("a1->print = %p\n", &a1->print); // compile error
    //printf("a2.print = %p\n", &a2.print); // compile error

    //printf("A::print = %p\n", A::print); // compile error
    printf("&A::print = %p\n", &A::print);
    a->print();
    a->v = 1;
    
    return 0;
}
执行结果:

&A::print = 0x100000eb0
print enter. this=0x0

a->v = 1;  // 空指针

那么问题来了。一般情况下,a=NULL, 为空指针,访问a都是非法的。但是 

1. a->v = 1; --> crash (这里没有任何问题,a为空指针,并未实例化)

2. a->print(); --> 输出 "print enter. this=0x0"

这是一个有意思的问题。我们先来看上面有4行printf() ,前面2个printf() 都是编译错误。

//printf("a1->print = %p\n", &a1->print); // compile error
//printf("a2.print = %p\n", &a2.print); // compile error
只有最后一个 
printf("&A::print = %p\n", &A::print);
能正确输出类函数地址,从以上现象可以看出,类函数并不是和类实例绑定的,它是编译后固有的,存储在代码段,是只读的。执行

$nm ./test

可以看到其中一行信息:

0000000100000eb0 t __ZNK1A5printEv

这个正是 &A::print 的地址。其实C++的类函数本质上跟C函数一样,只是默认增加了this 参数。

例如上面的 

void A::print();
等价于

void __ZNK1A5printEv(A* this);
这样理解也就没有问题了。a->print(); 只是查找到 &A::print 在代码段的地址,调用该函数,并把 (a=NULL)作为参数传入,输出的 this=0x0,也是证实了这一点。

而对于 A::v 变量,它是和类实例绑定的,只有生成了实例,A::v 才有对应的内存空间。所以访问A::v 的时候,必须保证已经实例化。



 

深入理解C++类:从声明到构造函数 本文通过C++类的声明、构造函数和析构函数的解析,探讨了面向对象编程的核心概念。文章首先分析了类的成员声明和可见性差异,然后通过实现栈类的示例,深入讲解了构造函数和析构函数的重要性与用法。 阅读详情

相关推荐

深入理解C++函数与类的精髓

本文通过探讨C++中的函数参数传递、函数原型、默认参数、函数重载和内联函数等概念,揭示了函数的高级特性和用法。同时,文章还介绍了C++的类和对象,从C结构体的回顾开始,逐步深入到类的设计和实现,为读者提供了全面且深入的理解。

weixin_30415591的博客 337

GDB简单教程

本文的内容基本来自http://www.cs.cmu.edu/~gilpin/tutorial/这篇教程,我在使用里面的示例程序时遇到了”<iostream.h> is not a file or directory” 的错误,因此修改了一下原来到源程序。 源代码: 为了使读者更快地学习gdb,本文提供了一个带有bug的示例程序,以及一个简单的makefile,我把他...

jubincn的专栏 399

C++编程:深入理解函数、对象与类

本文深入探讨了C++编程中的函数、对象和类的核心概念。章节内容涵盖了函数的声明与定义、参数传递方式、以及如何在C++中设计和使用对象。通过详细解析数组和字符串的处理、运算符重载以及继承和多态的实现,本文为读者提供了扎实的理论知识和实际编程技巧。

weixin_42518874的博客 296

c++ this 指针详解

首先来观察一段代码: class MyClass { int m_data; public: MyClass(int d = 0) : m_data(d) {} int data() const { return m_data; } }; void tmyclass() { MyClass obj1; MyClass obj2(100); cout << obj1.data(

hmalloc的专栏 1153

深入理解C++类与拷贝构造函数

本篇博客文章深入探讨了C++中类的概念,特别是拷贝构造函数的使用和重要性。通过对String类的详细分析,我们理解了拷贝构造函数如何在对象初始化、通过值传递对象给函数以及函数返回对象时被调用,以及如何正确地处理资源管理。

weixin_42181686的博客 796

深入理解C++中的String类与构造函数

本文通过深入探讨C++中String类的设计,特别是构造函数、复制构造函数以及析构函数的实现,揭示了自定义类管理动态内存的重要性。通过详细的代码示例和解释,我们了解到如何高效地管理资源,以及如何通过重载运算符来优化类的功能。

weixin_42113456的博客 385

C++入门系列5:this指针

C++入门系列5:this指针1:this指针 前言:C++入门系列文章,是按照鲍松山老师的C++入门课程进行的学习整理与记录,尊重原创,因此先附上鲍老师的视频链接:https://edu.51cto.com/course/4940.html,感谢鲍老师的悉心讲解与传授。 1:this指针 ...

xueping_wu的博客 514

深入理解C++类构造与函数操作

本文通过详细的代码示例,逐步介绍了C++中类的构造函数、成员函数、获取器(getter)和设置器(setter)的定义和使用。从默认构造函数的创建,到自定义构造函数的实现,再到成员函数的声明、定义和调用,展示了如何通过这些机制来操作和管理类的数据成员。文章还介绍了如何在主函数中创建和管理对象集合,并通过循环遍历这些对象。通过这些示例,读者可以更深入地理解面向对象编程的基本概念。

weixin_42611310的博客 151

C++学习(20)

1、  #include using namespace std; int main() { char *s="abcdefg"; s+=2; fprintf(stderr,"%d\n",s); return 0; } 分析:stdout-标准输出设备(printf(".."))同stdout;stderr--标准错误输出设备搜索;两者默认向屏幕输出。 但如果

王小东大将军的博客 656

深入理解C++类的构造函数和赋值操作

本文详细探讨了C++中类的构造函数的不同类型及其初始化方法,包括默认构造函数、带有默认参数的构造函数、用户提供的构造函数、成员初始化列表的使用、复制构造函数、自定义复制构造函数以及移动构造函数的概念和实践。通过具体的代码示例,文章揭示了如何在C++编程中实现对象的初始化、复制和移动操作,以及这些操作对于资源管理的影响。

weixin_42611310的博客 388

深入理解C++类与函数模板的应用

本文通过详细解读C++类和函数模板的使用,探讨了面向对象编程中类的概念以及如何通过函数模板提高代码复用性。文章从基础的结构体转换到类的定义、对象的创建和使用,以及函数模板的编写和重载,提供了丰富的代码示例和运行结果,旨在帮助读者深化对C++高级特性的理解。

weixin_42515340的博客 317

如何解决 read access violation at 0x0, flags= 0x0错误

在编译一个c++程序时报错 read access violation at 0x0, flags= 0x0。 出现这种问题的原因一般是变量没有被初始化。 所以,初始化一下你的变量就可以了

love4Mario的专栏 8128

深入理解C++编程语言中的类与函数

本文将深入探讨C++编程语言中类与函数的高级特性,包括类的成员函数、构造函数、析构函数、友元函数等。同时,将涵盖函数重载、异常处理、数据类型转换、I/O流操作等关键编程概念,以帮助读者更好地掌握C++编程的核心技能。

weixin_28729843的博客 479

深入理解c++的类静态函数

静态成员变量(如 “类的实例总数”)需要静态函数来访问或修改(普通成员函数依赖对象,无法直接操作类级变量)。将通用工具函数封装在类的静态函数中,避免污染全局命名空间,同时利用类的作用域组织代码。,隐藏构造细节(如根据参数生成不同子类对象,实现 “工厂模式”)。静态函数可封装与类相关的常量计算、枚举解析等逻辑,避免暴露细节。,保证全局仅一个实例,且无需提前创建对象。绑定的函数,核心特点是。

m0_75107602的博客 735

掌握C++类的深入理解:复制构造函数与友元函数

本文深入探讨了C++中类的复制构造函数和友元函数的使用和重要性。通过分析Date类和Employee类的构造和析构过程,我们了解到编译器默认提供的复制构造函数以及如何显式地通过成员初始化列表来初始化成员对象。此外,我们还探讨了友元函数的概念和用途,以及如何使用this指针来访问对象的成员变量。

weixin_42124497的博客 457

Minitab正交试验设计:从入门到精通的完整指南

本文提供了一份使用Minitab进行正交试验设计的完整指南。从正交试验省时省力的原理讲起,详细介绍了在Minitab中创建正交表、填入数据、执行分析(包括解读ANOVA和P值)以及寻找最优参数组合的全流程。文章旨在帮助读者,特别是工艺优化和研发人员,快速掌握这一高效工具,从而用最少的实验次数锁定关键影响因素,提升工作效率与成果。

weixin_29201313的博客 462

c++类中的函数调用类中的另一个函数_C++虚函数的深入理解

我们都知道代码运行时各个系统会为各种对象分配内存,每个具体的函数其实就是一个具体的对象,那么系统在程序运行时也会为每个方法分配对应的内存。而且之前有讲过,为了避免内存的浪费,所有同类的对象是共享同一函数内存的。但是当有继承发生时,函数调用方式是怎么样的呢?本篇内容就让我们一起来看一下:普通函数的调用方式:假设这里有一个很简单的类Base我们实例化出来一个类(Base b)然后在vs里用调...

weixin_32093689的博客 4982

通达信波段交易公式实战:如何用副图指标精准捕捉买卖点(附完整源码)

本文深入解析通达信波段交易副图指标的构建与应用,提供完整源码实现,帮助投资者精准捕捉买卖点。通过趋势强度度量、超买超卖判断及信号过滤机制,结合K线图分析,有效提升波段交易的成功率。

weixin_29306317的博客 601

C++类和对象(中篇):深入理解默认成员函数

刚学C++的来看!!!

wz_290793的博客 958

CTF-MISC:BUUCTF练习汇总(1-25题,不包括签到题)

解题思路:该题比较基础,wireshark打开过滤HTTP流量包,追踪HTTP流后可以看到base64密文,解密后得到jpg图片,打开图片即可看到flag,在线OCR识别即可提取出flag值。解题思路:zip压缩包解压需要密码,图片中的盲文为解压的密码,解压后得到MP3音频文件,内容为典型的摩斯密码;解题思路:由题目可以为LSB隐写,使用StegSolve打开图片查看最低有效位得到PNG信息,另存为图片后发现是二维码,扫描后即可得到flag。对应摩斯电码为:-.-. - …-. .-- .–. . …

燕麦葡萄干的博客 1万+

[DA45] 使用PageRank算法分析希拉里邮件中的人物关系

一. 相关知识 (一) PageRank算法 PageRank 算法是 google 公司的创始人拉里·佩奇和谢尔·盖布林于1998年提出的网页搜索优化算法. 详细内容请见百度百科:google pagerank. 如果你了解了该算法, 就能明白上一段的超链接从本页面链出, 链入百度百科的 PageRank 算法页面增加了该页面...

Vincent_Chu的博客 2375

【C++】类与对象:深入理解默认成员函数

C语言是面向过程的语言,强调函数和结构化编程,而C++在兼容C语言的基础上,增加了面向对象编程、泛型编程等特性。

yishaobai的博客 1158

【RT-DETR涨点改进】全网独家创新、细节涨点改进篇 | ICML 2024 | RT-DETR引入ICB交互式卷积模块和ASB自适应频谱模块,助力目标检测、异常检测有效涨点、含多种创新改进点

RT-DETR目标检测模型通过引入ICB和ASB模块实现性能提升。ICB模块采用多尺度卷积交互,有效捕获局部和长程依赖特征;ASB模块通过自适应频域滤波优化特征表示,降低噪声干扰。两者结合使模型在复杂场景中表现更优,显著提升检测精度和鲁棒性。文章详细介绍了模块原理、代码实现及配置方法,并提供了8种改进版本的YAML配置文件,适用于不同网络结构。这些创新改进为RT-DETR模型提供了高效涨点方案,特别适合复杂背景和高噪声环境下的目标检测任务。

Ai缝合怪、助力小伙伴高效发论文 211
上一篇: LINUX C中如何定义可变参数的宏
下一篇: Android JNI对象与Java对象的绑定
code09
博客等级 码龄18年 31粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值