在变量名前加上下划线 在变慢名前加上字母m 类的两种定义方法 将函数的定义和声明放在类里面实现: 这里使用class定义了一个日期类,在main函数里声明了一个day1对象,使用点操作符(.)...想要在类外实现类函数的定义,就必须使用上::域作用限定符 使用 Stack::,Stack指明了Init函数属于Stack类域 void Stack::Init(int capacity) { _next...三、this指针 Date类中有Init和print两个成员函数,函数体内没有为不同对象进行区别,在使用day1、day2调用 Init函数时,函数是如何区别是day1还是day2的。...this指针只能在成员函数内部使用,因为它是作为一个成员函数的形参,若是没有传递给当前对象地址的话,那么它的指向是不确定的。...,Print不存在对象里面,是在一块公共区域,若 p->_a这样写,就会出现空指针的解引用, _a是存在对象内部的,就像结构体里空链表对结构体成员的访问。
和 string 等在物理结上是连续的,所以可以直接将原生指针作为迭代器,而 list 不行,因为 list 的存储方式是链式结构,是分散的,所以不能直接对原生指针进行++等操作,所以得对 list 的指针进行封装...我们可以将 list 的原生指针进行封装,变成一个类,再对这个类进行运算符的重载,就能实现意义上的迭代器了! 2....举个例子: 对于析构函数: 迭代器里面虽然有一个节点的指针,但是该节点并不是由迭代器进行管理的,而是由 list 进行管理的,list 类的生命周期结束后会调用析构函数对节点进行释放的,而迭代器只是负责对该节点进行一些操作...解答: 如果我们要拿到的数据不是一个内置类型的数据,而是一个类的数据,那么情况就不太一样,以下面代码为例: //比如是一个日期类,假设我们没有实现其流插入,我们自己访问 struct Date {...凡是要取一个模板、类模板或模板参数的内嵌类型(内部类),就可以用 typename (不能用clss替代): [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3KHSEiy9
,如果没有下一个访问限定符的话 //那么这个访问限定符到};这个中间的空间都是外界能够进行访问的 //我们在函数后面加上private,那么这些函数就是公有的 //那么private到};中间的就是私有的...//一般来说的话成员函数一般是公有的 //成员的变量一般是私有的 //那么到这里我们就真正定义出了一个类 //类中有成员变量也有成员函数 //我们现在是能对类里面的的函数进行访问的,但是不能对类里面的变量成员进行访问..._day << endl; 这个this指针是隐含的 我们是不需要在实参和形参内写这个this指针 编译器自己会处理的 */ 这个this指针的作用本质还是给函数传对象的地址,然后根据这个对象进行区分数据...这两个题的区别就是在Print函数中是否有cout << _a << endl; 如果我们的this指针接收的是空指针的话 如果函数代码中存在打印成员变量的代码的话 多半会报错的 因为这个this指针会通过箭头隐含在代码中...这个this指针会指向这个变量进行解引用 但是这里的是空指针,空指针是不能进行解引用的操作的 所以这里是会报错的 this指针存在内存哪个区域的(A) A.
,实际上我们需要在内部实现; 2....类的两种定义方式: 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。...那么又有另外一个问题了,如果类里面只有一个成员函数或者空类是不是就没有大小了呢?...C++中通过引入 this 指针解决该问题,即:C++ 编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问...我们看结果: 代码可以正常运行,在这里,我们首先需要知道一个点,这个成员函数是否存在对象中,根据我们上面类对象模型所学,成员函数并不是存在对象中,它是存在公共代码区中的,而编译器在这里会进行处理,它不会解引用
static 类对象必须要在类外进行初始化,static 修饰的变量先于对象存在,所以 static 修饰的变量要在类外初始化; 由于 static 修饰的类成员属于类,不属于对象,因此 static...注意 extern 声明的位置对其作用域也有关系,如果是在 main 函数中进行声明的,则只能在 main 函数中调用,在其它函数中不能调用。...后续如果有一个基类类型的指针,指向派生类,那么当调用虚函数时,就会根据所指真正对象的虚函数表指针去寻找虚函数的地址,也就可以调用派生类的虚函数表中的虚函数以此实现多态。...当数据成员中没有指针时,浅拷贝是可行的。 但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针指向同一个地址,当对象快要结束时,会调用两次析构函数,而导致指野指针的问题。...动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。如果在当前工程中有多处对dll文件中同一个函数的调用,那么执行时,这个函数只会留下一份拷贝。
类的访问限定符 访问限定符说明: public修饰的成员在类外可以直接访问 protected和private修饰的成员在类外不能直接访问(此处protected和private是类似的,至于二者的区别需要在继承中体现...类的对象模型 对齐规则 在聊这个知识之前,如果你对C中如何计算结构体(对象)大小还不是很了解的话,(不是的话可以跳过这点)我们就先简单聊聊如何计算结构体大小。...这个类的大小是不需要考虑函数呢?还是算含有一个存放所有成员函数指针的函数指针数组?还是干脆算含所有成员函数指针呢?...C++中通过引入this指针解决该问题,即:C++编译器给每个非静态的成员函数(即没有static修饰的成员函数)增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有...C++中通过类可以将数据以及操作数据的方法进行完美结合,通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。
2)类的声明与定义 在前面我也提到了,struct的写法并不是一个标准类的写法,在C++中类的标准写法是需要关键字——class 的,那么该如何定义一个类呢?...我们在C语言中有个叫做 内存对齐 的东西(如果有些遗忘可以看看我的这篇文章:C语言内存对齐),但是在C语言中我们的struct内部是不存在函数的,所以我们对类进行sizeof会发生什么呢?...} int main() { Test(); return 0; } 如果只看私有成员变量,对C语言来说就是三个整形,那么sizeof后的结果不出意外是12,然而我们发现,我们对这个类的进行...那么既然成员函数不在类内部,如果是个空类(只有成员函数,无成员变量)呢?这个时候类的大小是多少呢?...; int _month; int _day; }; 我们可以看到this指针是默认指向类对象的成员变量的,既然this指针可以显示地写出来,那么是否也可以把this指针显示地放进形参里
,但是可以在外部定义 在类内定义的函数默认是隐式的内联函数 调用对象的成员函数时,实际上是将对象作为this指针指向的目标传入后执行了一个函数 也即是说,this是类的一个隐式常量指针,指向当前所用的这个实例对象...,常量指针指的是我们不能改变这个指针指向的地址 可以在成员函数的参数列表后面加上const,此时的成员函数称为常量成员函数,表示此时的this是一个常量版本的常量指针。...友元声明只能出现在类的内部,且此声明不受访问控制符的约束,为了清晰起见建议在类的开头或结尾集中声明 友元声明仅仅指示了权限,而不是传统的声明,所以要在类的外部再声明一次(尽管很多编译器不要求这个额外的声明...正因为这个顺序,当两者出现冲突时,函数内部的名的全称是this->[名],函数外的是[类名]::[名],函数外的作用域中的全称为::[名],注意此时是直接用空的双冒号即可。...多个参数的构造函数不会进行隐式转换 explicit只要能类内的声明中写,类外定义时不需要写 explicit关键字的构造函数只能用于直接初始化,即不能用在之后会说到的拷贝构造中 当一个类所有成员是public
2.类的两种定义方式 1.声明和定义不分离 即声明和定义都放在类中,注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。...5.类的作用域 类定义了一个新的作用域,类的所有成员都在类的作用域中。如果要在类体外定义成员,则需要使用 :: 作用域操作符指明该成员属于哪个类域。...如果按照这种方式存储,当一个类创建多个对象时,每个对象中都会保存一份成员函数的代码,相同代码保存多次,会导致空间浪费。那么如何解决呢?...:Data类中有InIt和Print两个成员函数,函数体中没有关于不同对象的区分,那么当d1调用InIt函数时,该函数时如何知道要设置d1对象而不是设置d2对象呢?...答:这个问题是因为C++中引入了this指针这个概念,即:C++编译器给每个“非静态的成员函数”增加了一个隐藏的this指针参数,让this指针指向当前对象(还是南湖运行时,调用函数的对象),在函数中所有
类体中内容称为类的成员,其中类的成员:1.类中的变量称为类的属性或成员变量2.类中的函称为类的方法或者成员函数类的两种定义方式:声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成...使类类型进行创建对象过称为类的实例化,如果出现没有对类进行实例化操作,而私自调用类中成员变量会报错,如:Person._age = 10。...char _a;};【问题】:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?...不将成员函数算入类内存中,而是将类成员函数存储在公共代码区空类比较特殊,编译器给空类一个字节来唯一标识这个类的对象,表示这个对象存在过,可能有成员函数。...C++中通过引入this指针解决该问题,即:C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问
同时,C++对C中的结构体struct进行了扩展和升级,struct结构体具有了和C++中类class基本相同的功能。...,也不方便去对类进行和调试,不能直观的分析类的功能。...C++中引入了this指针解决了这个问题:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数this,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有对成员变量 的操作...在计算类对象大小时,注意到类与C语言中结构体不同的是类域中有成员函数,那么类域中成员函数占不占类对象的大小呢?...C++中引入了this指针解决了这个问题:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数this,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有对成员 变量的操作
,但不能被模块外其他函数访问 在模块内的 static 函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内。...起到了隐藏的作用 在类的 static 成员变量属于整个类所拥有,对类的所以对象只有一份拷贝 在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的 static...关键字的总结 几个复制的声明 void * ( * (*fp1)(int))[10]; //fp1是一个指针,指向一个函数,函数参数为int,函数返回参数是一个指针,指针指向一个数组,数组中有10个元素...int (* ( * fp3)())[10](); //fp3是一个指针,指向一个函数,函数没有参数,函数返回值为一个指针,指针指向一个数组,数组中有10个元素,每个元素是一个函数指针,函数没有参数,...例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成内存泄露。)。 可以返回类成员的引用,但最好是const。
接下来就来看看类是如何定义的。 3. 类的访问限定符 定义一个类,使用时为什么会出现下面的问题呢? 这个是因为C++中有三种访问限定符。...类的两种定义方式: 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。 2....C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问...只能在“成员函数”的内部使用 this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。...这里没有解引用,因为不需要在p指向的空间去找。printA()不在p指向的空间上。不会去找,所以不会触发空指针。printA()的地址在编译时候就确定了。
可以直接将函数定义在类的内部,如果一个工程中定义多个数据结构,我们只需要将类进行实例化,不需要担心不同数据结构的函数回命名冲突。...类声明放在.h文件中,成员函数定义放在.cpp文件中 注意:成员函数名前需要加类名:: 标准正确定义的方法: 长的函数声明和定义分离;短小的函数可以直接在类里面定义 成员变量命名规则的建议: // 我们看看这个函数...有这样的一个问题: Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?...C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问...静态成员变量一定要在类外进行初始化!类里面声明,类外面定义 原因: 类里面初始化的缺省值,本质上是给初始化列表的,但是静态成员变量不要走初始化列表,因为初始化列表要定义一个对象里的成员。
,定义在类外 一般:类声明放在.h文件中,成员函数定义放在.cpp文件中 注意:成员函数名前需要加类名 : :(感觉跟命名空间一个用法) class Stack { private: int*...用类类型创建对象的过程,称为类的实例化(类 和 对象是 1对多的关系) 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表...:Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象 C++中通过引入this...指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。...<< "print()" << endl; cout 这个,对a指向的空间访问 } private: int _a; }; int main() { A* a = nullptr
就比如上面声明和定义分离的例子,如果有相同名字的成员函数定义(不是重载函数),那么就要说明这两个成员函数是属于哪个域的。 某个域::某个成员。 运行没任何问题。...类对象的存储方式 在C++设计的时候,考虑过类如果储存成员函数,那么创建多个对象的时候会非常的占用内存,导致栈溢出,就像造一个小区,每家每户没必要都有健身器材,只要在特定地点建造健身器材就好了,大家一起用...特性 类中每个成员函数都有一个隐藏的this指针,大概是这个样子的。...这也说明了一个问题,如果上面不去定义一个对象而直接通过类访问成员函数,那么会无法传参给this指针。 平时this指针不用写,编译器已经帮你处理了。...C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。
类域影响的是编译的查找规则,下面程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到_a等成员的声明/定义在哪里,就会报错。...8.1 this指针的引出 Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 和 Print函数时,该函数是如何知道应该访问的是d1对象还是...那么这里就要看到C++给了一个隐含的this指针来解决这里的问题,即:C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“...,也就是说不需要在对象里找函数的地址,这里p调用的意义是:第一,说明它是A类型的指针,就去A里面找这个成员函数(但是函数地址是在公共代码区里找);第二,传值给隐含的this(如果是对象,就把对象的地址传给...this,如果是指针就把指针传给this),传一个空指针并不会报错,只有用空指针进行访问才会报错。
用类类型创建对象的过程,称为类的实例化 比如 上面 域中的成员变量属于声明 对于变量而言 开空间属于它的定义 如 这个就是 对象的实例化 7.类的对象大小的计算 先来个 简单的题目...,因为静态成员函数没有this指针,只有非静态成员函数才有,且为隐藏指针. 5、this可以为空,单纯的对this赋空是不可以的,不过可以强转直接赋空,不过一般不进行这样的操作 1. this指针存在哪里...当我们在调用函数的时候,如果函数内部不需要通过this指向当前对象并对其进行操作时才可以为空(当我们在其中什么都不放或者在里面随便打印一个字符串);如果调用的函数需要指向当前对象,并进行操作,则会发生错误...例如: \ 3、返回指向对象的指针 在成员函数中,如果想要返回指向对象的指针,就可以使用this指针。...2.this关键字只能用于成员函数,不能用于被static修饰的函数(静态函数),因为静态成员函数没有this指针,它们仅能访问静态数据成员和静态成员函数 3.在C++中,this关键字是一个指向对象自己的一个指针
,我们用struct来定义一个结构体,那么定义一个与它同类型的变量要写成struct xxx的形式,而C++中用struct来定义一个结构体,那么同类型的变量则可以省略struct。...Person p;//p占有实际的物理空间,这里就是一个实例化的过程 //一个类可以进行多个实例化 Person p1; Person p2; 我们可以通过.操作符来实现类中方法的调用(public影响的区域可以在类外直接调用...this指针 在上面我们知道,成员函数是属于公有的,是类实例化后的各个对象所共同使用,那么不禁有一个问题,就是既然是公有的,那么它是怎么区分是谁调用的呢?...,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。...关于this指针为空 只要不涉及到解引用操作,程序都会正常运行,空指针也是可以调用类中的函数的,仅仅只凭借.或者->是不能判断是否涉及空指针的解引用,而是应该根据调用的函数的内容,来判断是否对空指针进行解引用
如果此时我们只是普通地重载了函数,那么我们根据指针所调用的函数是和指针的类型相同的,这称为静态绑定。...任何构造函数以外的非静态函数都可以是虚函数,如果基类声明了虚函数,那么派生类中的对应函数都隐式的是虚函数 通过抽象,我们使用动态绑定可以实现接口与实现的分离,基类用虚函数声明出接口,然后指针指向不同的派生类实现来动态调用...这里有一个特别的,即便处理的是基类指针,此指针指向某派生类,我们也不能隐式转换到这个派生类,如果基类中含有虚函数,我们可用用dynamic_cast强制转换 15.3 虚函数 通过对基类的指针或引用来调用虚函数时会出现动态绑定...,这个绑定在运行时才会确定,因此我们必须对每个虚函数都进行定义因为对虚函数的调用在运行时才解析,编译器也不能确定是否会被用到 运用这个动态绑定就是C++OOP的核心,多态性 一个派生类的函数如果想要覆盖继承来的虚函数...或constexpr,而是这个构造函数会继承基类中声明的属性 当基类构造函数中有默认实参时,这些实参不会被继承,而是派生类会得到多个继承的构造函数,每个构造函数省略一个有默认实参的形参 大多数时候派生类会继承基类的所有构造函数
领取专属 10元无门槛券
手把手带您无忧上云