自此结构体升级成了类,在类中定义的变量叫做成员变量,在类中定义的函数称为成员函数或者成员方法,不过一般C++定义类时更喜欢用“class”关键字。...(在C语言中是习惯先定义变量再使用),但是一般我们见到的C++程序都是将成员函数写在成员变量的前面,这是为什么呢?...类的作用域 前面有提到,class创建出来的类默认权限是private,而且在声明类时我们通常会将类的权限设置为私有,这就产生了一个问题就是说定义在类外的函数无法访问成员变量: 这个问题的解决方法就是使用域访问限定符...那么问题又来了,既然用的是同一个函数,而且我们也并没有将对象的地址传给函数,函数中也并没有区分对象的方法,那为什么却能输出出不同的结果呢?...此外类中只是声明,又不能在初始化列表中定义静态成员,那么静态成员应该在哪定义呢?
4.2为什么m_instance写在类外面 在C++中,静态成员变量是属于类的,而不是属于类的某个具体对象。这意味着无论创建多少个类的对象,静态成员变量只有一份拷贝。...那紧接着,就会问,那为什么GetInstance()函数定义不写在类外面呢,它写在类里不会报错,毕竟它也是static 在C++中,成员函数(包括静态和非静态)的声明通常在类的定义中进行,而定义(也就是函数体的实现...在C++中,this指针是一个特殊的指针,它指向调用成员函数的那个对象。你可以在类的非静态成员函数中使用this指针来访问调用该函数的对象的成员。...注意,我们还删除了复制构造函数和赋值操作符,以防止通过复制或赋值来创建新的实例。 6.怎么在main中创建单例 在main函数中创建单例的方式是通过调用单例类的全局访问点函数,也就是获取实例的函数。...在C++中,可以使用各种方法来序列化对象,包括手动序列化和使用库(如Boost.Serialization)。 反序列化是将序列化的数据恢复为对象的过程。
: 虽然经过上述构造函数的调用之后,对象中的成员变量已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋值。...当然: 在构造函数体内我们还可以再为成员变量赋值 注意这里成员_b被const修饰,不能再被赋值了。...那这样它就不再属于某个具体对象了,而是存储在静态区,为所有类对象所共享。 但是我们发现加了static之后报错了,为什么? 因为静态成员变量是不能在这里声明的时候给缺省值的。...那想解决这个问题,除了去写Get和Set方法,还可以这样解决: 就是声明日期类为时间类的友元类,这样在日期类中就可以直接访问Time类成员中的私有成员变量了。...然后呢,友元类还有一些需要我们注意的地方: 友元关系是单向的,不具有交换性 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量
静态方法成员 比如说类的静态成员函数。从学习中我们可以知道,类的静态成员表示这个类成员直接属于类本身;无论实例化这个类对象多少次,静态成员都只是一份相同的副本。那么什么时候去使用这个特性呢?...并且,这些方法在类中本来就只需要一份就可以了,节省了程序内存。 避免在全局作用域定义函数。一般的编程认为,定义在全局作用域的变量或者方法是不太好的。...实现 C++并没有静态类和静态构造函数的概念。在参考文献1中,论述了一些用C++去实现静态构造函数,从而更加合理的去初始化静态数据成员的办法。...其中一个实现是:我们需要的类按照正常的非静态成员类去设计,但是我们可以把这个类作为另一个包装类的静态成员变量,这样就能完美实现静态构造函数。...在实例化函数get_instance()内部,实例化了一个自身的局部的静态类。静态局部变量始终存放在内存的全局数据区,只在第一次初始化,从第二次开始,它的值不会变化,是第一次调用后的结果值。
---- ---- 一、struct ==> class(类 = 方法/成员函数 + 属性/成员变量) a. 在C语言阶段我们就已经认识到了结构体,它可以帮助我们实现多种数据结构,功能强大不言而喻。...但其实不是这样的,我们在计算过程中其实只关注了成员变量,至于函数并没有关注,这是为什么呢?这就涉及到实例化对象模型的设计了,我们往下再看看吧。 3.类对象的存储方式 a....我们不可以手动去传递this指针,这是编译器的工作,我们不能去抢,但是我们可以在函数体内部使用这个this指针。...之前我们所学的构造函数可以给新创建的对象赋初值,这点我们是知道的,但是它并不是对成员变量的初始化,而是赋值工作。 因为初始化只能初始一次,而构造函数内的赋值是可以赋值多次的。...但是反过来不可以,因为静态没有this指针,所以静态无法确切的指向某个具体的对象,自然就无法通过对象的地址(this指针)来获取到对象中的变量或函数方法。
6). c++中const成员为只读变量,可以通过指针修改const成员的值,另外const成员变量只能在初始化列表中进行初始化。 下面我们通过代码来看看区别。...静态(局部/全局)变量 2). 静态函数 3). 类的静态数据成员 4). 类的静态成员函数 9. 类的静态成员变量和静态成员函数各有哪些特性? 静态成员变量 1)....静态成员变量在类外单独分配存储空间,位于全局数据区,因此静态成员变量的生命周期不依赖于类的某个对象,而是所有类的对象共享静态成员变量; 3). 可以通过对象名直接访问公有静态成员变量; 4)....静态成员函数可以访问静态成员变量,但是不能直接访问普通成员变量(需要通过对象来访问);需要注意的是普通成员函数既可以访问普通成员变量,也可以访问静态成员变量; 3)....只有当参数是当前类的引用时,才不会导致再次调用拷贝构造函数,这不仅是逻辑上的要求,也是 C++ 语法的要求。 2) 为什么是 const 引用呢?
,对象个成员变量中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数函数体中的语句只能将其称为赋初值,而不能称作初始化;因为初始化只能初始化一次,而构造函数体内可以进行多次赋值;那么成员变量在哪里初始化呢..._i; N++; } private: int _i; }; 虽然使用全局变量的方法可以十分简便的达到我们的目的,但是我们不建议使用全局变量,因为全局变量可以被任何人修改,十分不安全;所以我们需要使用另外一种比较安全的方法...,当我们把类的静态成员变量设置为 public 并在类外进行定义初始化后,我们可以直接通过类名+域作用限定符或者通过一个空指针对象来访问,这说明_n并不存在于对象里面; 2、类的静态成员变量在类中只是声明...; 注:可以看到,静态成员变量在定义声明的时候只受类域的限制,而没有受到访问限定符的限制,这是一个特例,大家记住即可; 学习了静态成员变量的相关知识以后,我们就可以换一种方式来统计对象的创建个数了: class...但是重载为全局函数又会出现一个新的问题 – 在类外部无法访问类的私有数据;但是我们又不可能将类的私有数据改为共有,这样代价太大了,那么有没有一种办法可以在类外直接访问类的私有成员呢?
前言 在前两篇关于类和对象的文章中,我们学习了C++类的基本形式、对象的创建与使用以及每个类中都有的六大天选之子:默认成员函数,现在对类的基本框架已经搭好,关于类和对象的学习还存在一些细节,深入理解这些细节就是本文的主要目的...再调用拷贝构造函数,将临时变量的值拷贝给 aa1 我们可以看看打印结果是否真的如我们想的一样 结果:只调用了一次构造函数 难道编译器偷懒了?...,使其能在全局使用 修饰全局变量时,破坏其外部链接属性 static 修饰时,只能被初始化一次 static 不能随便乱用 ️static在类中 类中被 static 修饰的成员称为 静态成员变量 或...this 指针 静态成员函数是为静态成员变量而生 如此刁钻的成员变量究竟有何妙用呢?...--- 友元 新增关键字 friend ,译为朋友,常用于外部函数在类中的友好声明 类中的成员变量为私有,类外函数无法随意访问,但可以在类中将类外函数声明为友元函数,此时函数可以正常访问类中私有成员 友元函数会破坏类域的完整性
注意:构造函数不能为虚函数,但是析构函数可以为虚函数,并且虚析构函数可以防止父类指针销毁子类对象时不正常导致的内存泄漏。 12、C++中struct和class的区别?...定义时要分配空间,不能在类声明中初始化,必须在类定义体外部初始化,初始化时不需要标示为static;可以被非static成员函数任意访问。...static的第四个作用:C++中的类成员声明static 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;...浅拷贝: 在拥有指针成员的类中,一个对象利用拷贝构造函数或者赋值函数拷贝或者赋值给另一个对象的时候,直接将这个对象的指针成员赋值给另一个对象的指针成员,将一个指针赋值给另一个指针,就会使两个指针指向同一个空间...所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。
这种情况下,如果我们不提供任何实现,那么 C++ 编译器会自动为我们提供一个默认的构造函数、析构函数和拷贝构造函数和拷贝赋值运算符。 对于派生类来说,情况也是类似的。...(析构顺序为先派生类再基类) 另外,对于拷贝构造函数和拷贝赋值运算符来说,如果我们没有提供任何拷贝构造函数和拷贝赋值运算符,那么 C++ 编译器会自动为我们提供一个默认的拷贝构造函数和拷贝赋值运算符,其行为是浅拷贝...四、继承与静态成员 在 C++ 中,类可以包含静态成员变量和静态成员函数,其中静态成员变量属于类本身,而不是类的某个对象,因此它们可以在不创建类对象的情况下被访问。...在 main 函数中,我们可以直接通过类名来访问这些静态成员变量。...还有一个需要注意的点就是,类中只能声明静态成员,静态成员的定义只能在类外进行。 总之,在 C++ 中,静态成员在继承中的行为与普通成员有所不同,需要注意其使用方法。
在C++的学习中,可以把类当作一个模具,类所实例化出来的对象就是根据这个模具所产生的实体,对象可以看作是我们自己创建的一个新的数据类型。...不允许使用数据成员初始值设定项 }; 因此,初始化只能发生在类创建对象的过程中,但是由于访问权限的原因,无法在类外访问某些成员变量,因此下面这种做法有时候是无效的: circle C1; // 实例化一个对象...之所以说它特殊,是因为C++已经自动为构造函数提供了名称和使用语法,程序员只需要提供方法的定义即可,即:类名(形参列表)。...如前文所讲,C++会自动给类添加一个空的构造函数,但是如果自己在类中实现了有参构造函数,编译器便不再提供无参构造函数。...: 成员变量:静态成员变量和普通成员变量 成员函数:静态成员函数和普通成员函数 虽然为了集成,我们将其写到一个类里面,但是只有普通成员变量真正属于类的对象,类的所有对象共享一份静态成员函数,静态成员变量和普通成员函数
静态成员变量一定要在类外进行初始化。 静态成员是指属于类而不属于类的任何对象的成员。静态成员在类的所有对象之间共享,并且可以在不创建对象的情况下被访问。静态成员包括静态变量和静态方法。...在非静态成员函数中,可以使用类名和作用域解析操作符(::)来调用静态成员函数。...三、static成员的注意事项 static不能给缺省值 在C++中,static关键字用于声明静态成员变量或静态函数。在声明静态成员变量时,不能直接为其设置缺省值。...因此,为了保证静态成员变量的可靠性,最好在类外部进行初始化赋值。 static修饰变量和修饰函数的区别 C++中,static关键字可以用于修饰变量和函数,并且在两者之间有一些区别。...静态变量的初始化只会在程序第一次进入声明它的作用域时执行一次,并且只能在声明时给定初值。 静态变量的作用域限制在声明它的函数或类中,但它的值在函数调用之间保持保持不变。
被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。...6、静态方法不能被重写为非静态的方法(会编译出错)。 重载的规则: 1、在使用重载时只能通过相同的方法名、不同的参数形式实现。...对于多重继承的派生类来说,它含有与父类数量相对应的虚函数指针。 2. 为什么基类的构造函数不能定义为虚函数?...解决二义性的方案:利用作用域运算符::,用于限定派生类使用的是哪个基类的成员;在派生类中定义同名成员,覆盖基类中的相关成员。 6. 如果类A是一个空类,那么sizeof(A)的值为多少?...C++的空类有哪些成员函数 默认构造函数、 默认拷贝构造函数、 默认析构函数、 默认赋值运算符,以及取址运算符和 const 取址运算符。 10. 虚函数表属于类还是对象?虚函数表什么内存空间?
这其实就在向我们传达了一个信息:初始化过程是在进入构造函数之前完成的!! 所以构造函数的本质并不是初始化成员变量,而是给成员变量赋值!!...1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。...因为初始化只能初始化一次,而构造函数体内可以多次赋值。 回到我们之前增加const变量的情况,那我们想要在类里面弄一个const修饰的成员变量怎么办呢??...成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后 次序无关 可以理解为声明顺序就代表初始化顺序,与你写的先后顺序无关,如上虽然我们先写a1但是会先对a2初始化,此时a1...这样虽然可以解决问题,但是也会有另一个问题就是这个count是一个全局变量,也就是说我有可能在写程序的时候会不小心修改它,比如说++了一下 这就很尴尬的了,所以我们希望该变量可以在构造函数里被访问到,
然后呢,我还想定义一个学生类,那此时我还需要重新从0开始定义一个类吗? 当然也是可以的。但是像这种情况,使用继承就会非常香。 为什么这种情况可以使用继承呢?...(在子类成员函数中,可以使用 基类::基类成员 显示访问)。 我们继续,刚才是子类和父类中出现同名的成员变量,那如果是出现同名的成员函数呢?...我们发现这里我们自己初始化继承下来的_name成员但是报错了。 为什么不行呢?那这里要告诉大家的是: 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。...Person不是有一个静态成员变量_count吗,只需在Person的构造函数里面加一句++_count就行了 为什么这样就可以呢?...,那在类外确实调不了,但在类里面可以啊,所以我们可以提供再一个函数去作为创建对象的方法 但是非静态成员函数的通过对象去调用啊,可是现在没对象怎么调? 那我们就可以把它搞成静态的。
,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。...这里是显示的调构造 【注意】 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次) 类中包含以下成员,必须放在初始化列表位置进行初始化,不能在函数体内初始化: (1)引用成员变量...不会,2构造一个临时对象,再拷贝构造 -> 编译器优化了,同一个表达式连续步骤的构造,一般会被合二为一 这个代码为什么可以? 类型转换会产生临时变量。...到时候初始化列表就直接用2去初始化,和上面的原因一样:同一个表达式连续步骤的构造,一般会被合二为一 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。...this指针 3.2 特性 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明 类静态成员即可用 类名::静态成员
(如上图) (1) 初始化列表的作用: 我们未使用初始化列表之前,一直都是在函数体内赋值,那初始化列表有什么用呢? 试着看一下下面这段代码....静态成员函数可以直接通过类名进行调用,而不需要创建类的实例对象。 (2)静态成员函数为什么一定要在类外面初始化: C++中的静态成员变量在程序运行时被分配内存,但是它们的定义是在编译时就已经完成的。...在声明静态成员变量时,需要在类的定义中进行,但不能在函数内部进行。在类的定义中声明的静态成员变量不会占用内存空间,只有在类外定义时才会真正地分配内存。...工具函数:静态成员函数可以作为工具函数,独立于对象的操作,提供一些辅助功能。 静态成员变量和静态成员函数为类提供了与类相关的特性和功能,并且可以在不创建类的实例对象的情况下进行访问和使用。...,不能访问类中的私有成员和保护成员,但是友元函数却可以,一个特殊的存在,由于这样操作破坏了类的封装性,我们建议少使用友元.
4.static的第四个作用:C++中的类成员声明static 1) 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;...所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。...成员初始化列表的概念 在类的构造函数中,不在函数体内对成员变量赋值,而是在构造函数的花括号前面使用冒号和初始化列表赋值 效率 用初始化列表会快一些的原因是,对于类型,它少了一次调用构造函数的过程,而在函数体中赋值则会多一次调用...但是对象a的空间还在呀(在析构之前),既然拷贝构造函数,实际上就是把a对象的内容复制一份到b中,那么为什么我们不能直接使用a的空间呢?...当退出函数的时候,临时变量可能被销毁,但是返回值却被放到寄存器中与临时变量的生命周期没有关系 如果我们需要返回值,一般使用赋值语句就可以了 《【C++】临时变量不能作为函数的返回值?》
到这里小白可能会问,为什么我们还没有创建对象就可以访问类中的内容呢?这就涉及到了关键字static的使用方法。 ...2.静态代码块 静态静态块也是static的重要应用之一。通常使用于类的初始化,和静态变量、静态方法一样,静态块里面的代码只执行一次,且只在初始化类的时候执行。...2.static在类加载时就创建好了内存空间,但是它的内容是可以改变的,我们可以通过不同的对象给它赋值,但是它的值取决于你最终给它的赋值。...静态修饰的优点 1.方便在我们没有创建对象时,调用类中的方法/变量 2.static可以用来修饰类的成员方法、成员变量或编写static代码块,能够有效地优化程序性能 我们可以通过下面一段代码来直观地感受一下...1.static不会改变类中成员的访问权限 很多初学者容易把java中的static和C/C++中的static搞混了,在C/C++中,static能够改变成员的访问权限,而这在java中时不行的,在
一、特殊类设计 1.1 不能被拷贝的类 拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。...将类的构造函数私有,拷贝构造声明成私有(可以直接delete掉)。防止别人调用拷贝在栈上生成对象。 注意:拷贝构造可以直接delete掉,但是构造函数不行!!...因为我们还需要利用构造函数在堆上创建对象。 2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。...在堆上创建对象是用指针去接受,所以并不影响,但是内存需要我们去手动释放,因此我们需要封装destory的成员函数去调用delete,这样delete可以对应调用到析构函数。...思考: 1、为什么父类和子类明明是两种类型,但是向上转型不需要转换呢??
领取专属 10元无门槛券
手把手带您无忧上云