您好,欢迎访问三七文档
C++的个人笔记类的声明及定义1.class、struct、union保留字都可以用来声明和定义类。class中成员默认为private类型,struct、union与C语言兼容,成员默认为public类型。2.只有当类没有显式的定义构造/析构函数时,C++才会提供默认的构造/析构函数;默认的构造函数只负责创建对象,不做任何初始化工作。3.程序正常退出时,析构函数会被隐式调用;非正常退出(如abort)则析构函数不会被调用,可能导致系统资源没有及时得到回收。构造函数只能被隐式调用,析构函数可以被显式调用。4.对象在退出其作用域时自动析构,其对象的析构顺序与其创建的顺序相反;常量对象在创建之后立即析构。类成员的访问权限1.private说明的对象成员是完全私有的,即便是派生类的后代对象也不能访问这类成员。2.protected说明的对象成员是私有的,受保护的,该对象派生的后代可以访问这类成员。3.public说明的对象成员是完全公开的,任何对象都能访问这类成员。4.无论什么类型的的对象成员,都可以被友元函数访问。5.类的访问权限只能防止无意识的越权访问,通过强制类型转换,可对类的成员无限制的进行访问。内联函数1.不管是否出现inline保留字,在类体内定义的任何函数成员都会自动成为内联函数。2.在类题外定义内联函数,必须用inline显式的加以说明。3.内联函数的定义必须出现在内联函数第一次调用之前,否则以普通形式调用(内联失败new和delete1.对于简单类型以及没有定义构造和析构函数的类,malloc/free及new/delete两种内存分配方式可以混用;若类定义了构造函数和析构函数,则最好使用new和delete来分配和释放内存。2.在用new为数组分配空间时,数组的第一维下标可以是动态的,其它维则要求是静态的,即必须为整型常量或常量表达式;如果数组元素的类型为类,且希望用new创建对象数组,则相应的类必须定义无参数的构造函数,如果没有定义任何构造函数则使用C++的无参数构造函数。3.在全局空间重载new、delete运算符,则全局空间中的使用new、delete将是重载版本。4.在类空间重载new、delete运算符,则对于该类的new、delete将使用类的重载版本。5.delete不需要测试指针是否为0,因为在delete的实现中已经考虑到了,没有必要进行重复的测试隐含的this指针1.类的普通成员函数比静态成员函数多了一个隐含参数this指针,隐含this指针是普通成员函数的第一个参数,该参数的类型为指向此类对象的const指针。2.this可以用来区别与该函数成员参数同名的数据成员3.this可以用来访问调用该函数成员的对象、对象的地址和对象的引用。4.在非const成员函数中,const的声明如:C*constthis;在const成员函数中,const的声明如:constC*constthis;对象初始化1.若类定义了构造函数,则其对象必须用类定义的构造函数进行初始化;当类含有只读和引用类型的非静态数据成员时,类必须为这些成员定义构造函数。2.假定数据成员类A包含B类的非静态数据成员,如果B类定义了带参数的构造函数,则A类必须定义自己的构造函数,不能使用C++缺省的构造函数。3.构造函数必须初始化对象的对象成员,只读成员和引用成用,且只能在构造函数的函数体前初始化一次;其他数据成员可以在构造函数的函数体前初始化,也可以在构造函数的函数体内再次初始化。4.数据成员按其在类中定义的顺序初始化,而与他们出现在构造函数体前的顺序无关。如果简单的类型数据成员没有出现在构造函数的函数体前,则他们的值将被缺省的初始化为0。5.在定义的时候使用Aa=A()时,与Aa()一样,只调用构造函数,不调用operatorn名字空间1.namespace保留字用于定义名字空间。名字空间必须在程序的全局作用域内定义,不能在函数内定义,最外层名字空间的名称必须在程序的全局作用域内唯一,名字空间可分多次定义。没有名称的名字空间称为匿名名字空间,每个程序只能有一个匿名名字空间。2.using保留字用于声明程序要引用的名字空间成员,或者用于指示程序要引用的名字空间。如usingA::x,则将x引入到了代码所在的作用域,不能再重复定义x;而如果使用usingnamespaceA,则仍可定义x,但须按照A::X才能访问到A中的x。3.名字空间可以定义别名,以代替过长和难懂的名字空间名称,如namespaceABCD=A::B::C::D,则以后直接可以用ABCD来访问多重名字空间。const、volatile、mutable1.使用const声明不可变的数据成员,函数成员的参数和返回值等,包含const成员的类必须定义构造函数。2.volatile修饰的变量表示其可能被并发访问(修改),该保留字告诉编译器不要对变量的访问做任何访问优化,即不利用寄存器存放中间计算结果,直接访问对象以便获得对象的最新值。3.普通函数成员的参数表后可以出现const或volatile,其修饰的是函数成员隐含参数this指针指向的对象。4.mutable修饰的数据成员是易变的,mutable成员总可以被更新,即使在const类型的成员函数中。引用1.引用时变量的别名,可以通过别名直接访问被引用的变量;而指针变量的值是变量的地址,指针是通过地址间接访问变量的值。2.引用必须被初始化,且初始化之后不能再做其他变量的引用(别名),引用参数则在函数调用时进行初始化。3.引用可用于做函数的参数或返回值,避免了传递参数时大量数据的拷贝。4.在目标代码中,引用是不存在的,需要使用引用的地方,已经尤其引用的对象替代了。引用对象1.引用变量是对引用变量的别名,对被引用的变量必须进行构造和析构,而引用变量本身没有必要构造和析构。2.普通引用变量必须用左值初始化,如果用右值表达式进行初始化,就会生成一个临时的匿名变量,引用参数也一样;如A&q=newA(3),则在使用完q后必须delete&q,以释放临时匿名变量的空间。3.非引用类型的形参是作用域限于函数的局部变量,形参对象的析构是在函数调用返回前完成的,至于形参对象的构造则是在调用时由值参数传递的,值参数传递将实参各数据成员的值相应地赋给形参的数据成员,对于指针类型的数据成员则只复制指针的值,而没有复制指针所指向的存储单元,即进行浅拷贝。如果类中含有指针成员,则进行浅拷贝可能导致内存错误,必须定义拷贝构造函数,在函数调用时使用拷贝构造函数进行深拷贝。静态数据成员1.静态数据成员用于描述类的总体信息,必须在类的体外进行定义并初始化。2.静态数据成员脱离具体对象独立存在,其存储单元不是任何对象存储空间的一部分,但逻辑上所哟对象都共享这一存储单元,在计算对象或类的存储空间时不能包含静态数据成员。3.静态数据成员描述类的总体信息,由于全局类作用与所有程序文件,故全局类的静态数据成员也必须作用于所有程序文件,即定义的时候是intP::q=0,而不是staticintP::q=0,但在类中声明时要加上static。4.union的数据成员必须共享存储空间,而静态数据成员各自独立分配存储单元,故静态数据成员不能成为union的成员。5.静态数据/函数成员可通过三种方式访问:(1)A::member(2)a.A::member(3)a.member静态函数成员1.普通成员函数的第一个参数为隐含this指针,而静态函数成员没有隐含的this参数。2.构造函数、析构函数、虚函数等有this指针,若函数成员的参数表后出现const、volatile,则该函数成员的参数表必包含隐含的this指针,这些函数不能定义为静态函数成员。3.union不能定义静态数据成员,但可以定义静态函数成员。从C转向C++1.尽量用const和inline而不用#define2.尽量用iostream而不用stdio.h3.尽量用new和delete而不用malloc和free拷贝构造函数调用场合1.一个对象以值传递的方式传入函数体2.一个对象以值传递的方式从函数返回3.一个对象需要通过另外一个对象进行初始化函数重载与默认参数1.C是弱类型的语言,在调用函数时,实参的类型和数目可以同函数原型不一致;而C++是强类型的语言,调用时实参的个数和类型都必须同函数原型一致。2.函数的参数个数或者类型不同,则同名的函数被视为重载函数。3.不能同时在函数的原型声明和函数定义中定义缺省参数(声明或定义任一位置指定默认参数即可),在调用函数是,非缺省的参数必须传递实参,所有缺省的参数必须出现在非缺省参数的右部。4.编译时通过匹配实参和形参来确定要调用的重载函数,当调用重载函数时,若找不到匹配的函数,或是找到多个匹配的函数(有默认参数的情形),编译程序均将报错。运算符重载1.重载不改变运算符的优先级和结合性,一般情况下,重载也不改变运算符操作数的个数(++/--需要区分前置还是后置运算符,-改变了操作数的个数)。2.除sizeof.*::和三目运算符?:外所有的运算符都可以重载;运算符=-()[]只能重载为类的普通函数成员,不能重载为静态函数成员或普通函数。3.运算符重载是面向单个类对象的,而不是面向简单类型或常量的。如果将运算符重载为普通函数,就必须至少定义一个引用类或者类的参数,且参数不能是对象的指针或者是对象数组类型。4.如果重载左值运算符(如+=、=等),则重载后运算符最好返回引用类型,重载为普通函数的运算符通常为了方便数据访问,将其设为类的友元。5.为了区分单目的前置运算符与后置运算符(++、--),在重载为后置运算符时,加一个额外的int参数作为标识。6.运算符重载可用于强制类型转换,如对某个类实现operatorint()const{};(const表示强制类型转换不改变当前对象的值),则当类向int转换时,该函数会被调用。静态绑定与动态绑定1.静态绑定:编译时绑定,通过对象调用;动态绑定:运行时绑定,通过地址实现。2.静态多态性:函数多态性——函数重载模板多态性——C++模板(类模板、函数模板)3.动态多态性:虚函数(只有用地址才能实现动态多态性)4.只有采用“指针-函数()”或“引用变量.函数()”的方式调用C++类中的虚函数才会执行动态绑定。对于C++中的非虚函数,因为其不具备动态绑定的特征,所以不管采用什么样的方式调用,都不会执行动态绑定。.执行动态绑定的只有通过地址,即只有通过指针或引用变量才能实现,而且还必须是虚函数。从概念上来说,虚函数机制只有在应用于地址时才有效,因为地址在编译阶段提供的类型信息不完全。模板与继承1.当对象的类型不影响类中函数的行为时,就要使用模板来生成这样一组类,如一个支持泛型的堆栈类。2.当对象的类型影响类中函数的行为时,就要使用继承来得到这样一组类,如一个拥有不同特性的猫类。虚函数1.重载函数时一种静态多态函数,其通过静态绑定完成;虚函数是一种动态多态函数,其通过动态绑定完成。动态绑定的效率非常高,仅比静态绑定多了一次指针访问。2.虚函数以virtual标示,在基类中定义虚函数,派生类原型相同的函数将自动成为虚函数,不管进行多少级派生,虚函数的特性将一直保持下去。3.虚函数具有隐含的this指针,故虚函数不能定义成静态成员函数。构造函数拥有隐含的this指针,但构造函数的对象类型必须是确定的,不需要表现出多态性,故构造函数不能定义为虚函数。4.对于基类和派生类的虚函数,其原型必须完全相同,但其访问权限可以不同。5.虚函数可以定义为inline,也可以重载,缺省和省略参数。函数模板1.通过保留字template声明模板,声明中模板的参数表必须用尖括号括起来,每个参数必须在函数参数表中至少出现一次,参数表中的参数可以在实现中并没有使用。在套用函数模板生成模板函数时,函数模板参数表的每个
本文标题:c++小知识
链接地址:https://www.777doc.com/doc-2901661 .html