C++的一些总结

1当用类的一个对象初始化该类的另一个对象时
int main()
{
point A(1,2);
point B(A);//用对象A初始化对象B,拷贝构造函数被调用.
}

2函数的形参是类的对象,调用函数时,进行形参和实参结合时.
C/C++ code
void f(point p)
{
}
main()
{
point A(1,2);
f(A);//函数的形参为类的对象时,当调用函数时,拷贝构造函数被调用.
}

3 如果函数的返回值是类的对象,函数执行完成返回调用者时.
C/C++ code
point g()
{
point A(1,2);
return A;//函数的返回值是类的对象,返回函数值时,调用拷贝构造函数.
}
void main()
{
point B;
B = g();
}
4、需要产生一个临时类对象时。

默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。
它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义。如果定义某个类的变量时没有提供初始化时就会使用默认构造函数。
cin大于
cout小于

深刻体会使用友元函数与继承成员函数的巨变

多态性指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:
编译时多态性,运行时多态性。
a.编译时多态性:通过重载函数实现
b 运行时多态性:通过虚函数实现。

protected Members

The protected access label can be thought of as a blend of private and public :

Like private members, protected members are inaccessible to users of the class.
Like public members, the protected members are accessible to classes derived from this class.
In addition, protected has another important property:
A derived object may access the protected members of its base class only through a derived object.
The derived class has no special access to the protected members of base type objects.

基类对象不能访问基类的protected成员,派生类中可以访问基类的protected成员。
也就是说private成员是不能被继承的,只有public,protected的成员才可以被继承。
派生类对象如果要访问基类protected成员只有通过派生类对象,派生类不能访问基类对象的protected成员。
只有在派生类中才可以通过派生类对象访问基类的protected成员。

指针访问不同地址的同名函数结果不同
虚函数重载要求参数一样
继承不会继承构造函数和析构函数
父类指针可以指向子类对象
运算符重载实质上也是一种函数重载
“=”一个对象给另一个对象赋值,系统已经定义好了这个重载函数
将成员函数写在public是对类封装性的极大破坏
有时也需对“=”重新重载
动态成员不能脱离对象,属于某个对象
浅层拷贝(指针悬挂)同一个地址不能被释放两次
下标运算符[ ]重载只能用于成员函数

转换构造函数是一个构造函数
是一个参数的构造函数
把任意的一个量(常量/变量)转化为一个对象
一个参数的构造函数(转换构造函数)不是本类的const引用
拷贝构造函数是本类的const引用
转换构造函数只能有一个参数,有多个成员变量时只能顾一个

转换构造函数的例子
整数转化为整数类的对象

cout只能输出基本类型,不能输出对象
把某一个类型做重载:把一个对象转化为某种类型的数据(类型转换函数的功能)

指针无实体,指向内容
返回值类型不同不影响重载,
虚函数同名同变量
{
1.名一致,参数(类型,数量,顺序)一致
2.返回值类型不用一致
}
!!!!!!在类外定义不要加virtual
动态调用需要通过指针进行
C++ new声明 必须用delete释放掉,否则永久占用内存

虚函数用来解决被遮挡问题
多态性即虚性
父类有虚函数,子类必有虚函数
虚函数函数名在父类中定义
父构->子构->子析->父析(->父析(拷贝构造函数))

纯虚函数保证基类只是一个概念,纯虚函数与函数体为空完全不一样
0无实质内容,仍是数字
有函数体(空语句)
纯虚函数virtual void show()=0;
virtual 函数类型 函数名(参数表)=0;
抽象类(类存在,但不能用类来新建对象,不允许存在实体的类)
抽象类的类型实例化必须实现类->其子类不再是抽象类
抽象类可以有构造函数析构函数,只是不能实例化。

delete p;
释放堆空间后,p成了空悬指针
释放该对象所占堆空间,并只能释放一次,在函数内建立,而在函数外释放是一件很容易失控的事,往往会出错。
通过new建立的对象要调用构造函数,通过delete删除对象也要调用析构函数。
CGoods *pc;
pc=new CGoods; //分配堆空间,并构造一个无名的CGoods对象;
…….
delete pc; //先析构,然后将内存空间返回给堆
堆对象的生命期并不依赖于建立它的作用域,所以除非程序结束,堆对象(无名对象)的生命期不会到期,
并且需要显式地用delete语句析构堆对象,上面的堆对象在执行delete语句时,C++自动调用其析构函数。

正因为构造函数可以有参数,所以new后面类(class)类型也可以有参数。
这些参数即构造函数的参数。但对创建数组,则无参数,并只调用缺省的构造函数。
eg.
class CGoods{
char Name[21]; int Amount;
float Price; float Total value;
public:
CGoods(){}; //缺省构造函数。
CGoods(char* name,int amount ,float price){
strcpy(Name,name);
Amount=amount;
Price=price;
Total_value=price*amount;  }
……}
使用:
void main(){
int n;
CGoods *pc,*pc1,*pc2;
pc=new CGoods(“夏利2000”,10,118000);
//调用三参数构造函数
pc1=new CGoods(); //调用缺省构造函数
cout<<’输入商品类数组元素数’<<endl;
cin>>n;
pc2=new CGoods[n];
//动态建立数组,不能初始化,调用n次缺省构造函数
……
delete pc; delete pc1; delete []pc2;
}
!!!由堆区创建对象数组,只能调用缺省的构造函数,不能调用其他任何构造函数。
如果没有缺省的构造函数,则不能创建对象数组。

!!!(浅拷贝与深拷贝,自己看图)
缺省拷贝构造函数,可用一个类对象初始化另一个类对象,称为缺省的按成员拷贝,
而不是对整个类对象的按位拷贝。这称为浅拷贝。
重新定义拷贝的构造函数,给每个对象独立分配一个堆对象,称深拷贝。
如果类需要析构函数来析构资源,则类也需要一个自定义的拷贝构造函数。对象的拷贝就是深拷贝了。

!!!在C/C++中允许结构(或对象)成员是结构自身的指针类型,通过指针引用自身这种类型的结构。
但结构成员决不能是结构自身类型,即结构不能自己定义自己,这会导致一个无穷递归的定义。
!!!公有派生是绝对主流。

类的派生与继承
{
吸收基类成员:不论是数据成员,还是函数成员,除构造函数与析构函数外全盘接收
改造基类成员:声明一个和某基类成员同名的新成员,派生类中的新成员就屏蔽了基类同名成员称为同名覆盖(override)
发展新成员:派生类新成员必须与基类成员不同名,它的加入保证派生类在功能上有所发展。
重写构造函数与析构函数
}
访问限定符有两方面含义:
{
派生类成员(新增成员)函数对基类(继承来的)成员的访问(调用和操作)
从派生类对象之外对派生类对象中的基类成员的访问
}

派生类的构造函数与析构函数

派生类的构造函数的定义形式:
派生类名::派生类名(参数总表):基类名1(参数表1)成员对象名1(成员对象参数表1){
……//派生类新增成员的初始化;
} //所列出的成员对象名全部为新增成员对象的名字
!!!在构造函数的声明中,冒号及冒号以后部分必须略去。
!!!所谓不能继承并不是不能利用,而是把基类的构造函数作为新的构造函数的一部分,或者讲调用基类的构造函数。
冒号后的基类名,成员对象名的次序可以随意,这里的次序与调用次序无关。

派生类构造函数各部分的执行次序为:
1.调用基类构造函数(按它们在派生类定义的先后顺序,顺序调用)。
2.调用成员对象的构造函数(按它们在类定义中声明的先后顺序,顺序调用)。
3.派生类的构造函数体中的操作。
!!!在派生类构造函数中,只要基类不是使用缺省构造函数都要显式给出基类名和参数表。
如果基类没有定义构造函数,则派生类也可以不定义,全部采用系统给定的缺省构造函数。
如果基类定义了带有形参表的构造函数时,派生类就应当定义构造函数。
析构函数各部分执行次序与构造函数相反,
{
首先对派生类新增一般成员析构,
然后对新增对象成员析构,
最后对基类成员析构。
}
由多个基类共同派生出新的派生类,这样的继承结构被称为多重继承或多继承(multiple-inheritance)

唯一标识问题。通常采用作用域分辨符“::”
{
基类名::成员名;//数据成员
基类名::成员名(参数表);//函数成员
}

(可以看看PPT例子)
如果class Person的身份证号标识为int IdPerson,
则可写为:
EGStud1.GStudent::IdPerson
EGStud1.Employee::IdPerson
不必标出那么多层次的类,但写EGStud1.IdPerson是错的。
采用有确定字面意思的标识符,可以被编译器简单区分出来。
!!!!!!作用域分辨符不能嵌套使用,如:
EGStud1.GStudent::Student::No //学生号
EGStud1.GStudent::Student::Person::No //身份证号
均是错误的。

!!!!!!一般数据成员总是私有成员,派生类对基类的访问只能间接进行。
访问身份证号,应通过class Person中的公有成员函数(接口)GetNo()和SetNo()进行:
EGStud1.Employee.Person::SetNo(int no);
no=EGStud1.Employee.Person::GetNo();

二义性问题/歧义性问题(解决方式:引入虚基类)

虚基类(virtual base class)定义方式:
class 派生类名:virtual 访问限定符(/继承方式) 基类类名{…};
把共同基类设置为虚基类,这样从不同路径继承来的同名数据成员在内存中就只有一个拷贝,同名函数也只有一种映射。
!!!!!!
一个基类在作为某些派生类虚基类的同时,又作为另一些派生类的非虚基类,这种情况是允许存在的,即我们所说的虚实结合
但Java对类的继承只有一种单继承,不用考虑这些(虚基类:继承同一个类A/二义性/两边互质 &虚实结合)
virtual 关键字只对紧随其后的基类名起作用

(看图)在Person的位置上放的是指针,两个指针都指向Person成员存储的内存。这种继承称为虚拟继承(virtual inheritance)

在派生类对象的创建中,构造函数各部分的执行次序
{
首先:虚基类的构造函数并按它们声明的顺序构造
第二:非虚基类的构造函数按它们声明的顺序调用
第三:成员对象的构造函数
最后:派生类自己的构造函数被调用
}
析构的次序与构造的次序相反。

eg.
class Dclass:public Bclass1,virtual Bclass3,virtual Bclass2{
Object object;
public:
Dclass():object(),Bclass2(),Bclass3(),Bclass1(){
cout<<“派生类建立!\n”;}
~Dclass(){cout<<“派生类析构!\n”;}};
void main(){ Dclass dd; cout<<“主程序运行!\n”;}
运行结果
Constructor Bclass3
//第一个虚拟基类,与派生类析构函数排列无关
Constructor Bclass2 //第二个虚拟基类
Constructor Bclass1 //非虚拟基类
Constructor Object //对象成员
派生类建立!
主程序运行!
派生类析构!
deconstructor Object //析构次序相反
deconstructor Bclass1
deconstructor Bclass2
deconstructor Bclass3 //析构的次序与构造的次序相反。

在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则。
{
1.派生类的对象可以赋值给基类的对象,这时是把派生类对象中 从对应基类中继承来的成员赋值给基类对象。
反过来不行,因为派生类的新成员无值可赋。
2.可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,
不能访问派生类中的新成员。同样也不能反过来做。
3.派生类对象可以初始化基类的引用。引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。
}

虚函数是一个类的成员函数,定义格式:
virtual 返回类型 函数名(参数表);
!!!!!!关键字virtual指明该成员函数为虚函数。virtual仅用于类内定义中,如虚函数在类外定义,不可加virtual。
!!!!!!当某一个类的一个类成员函数被定义为虚函数,则由该类派生出来的所有派生类中,该函数始终保持虚函数的特征。
当在派生类中重新定义虚函数(overriding a virtual function,亦译作超载或覆盖)时,不必加关键字virtual。
但重新定义时不仅要同名,而且它的参数表和返回类型全部与基类中的虚函数一样,否则联编时出错。

改造类成员,同名覆盖(override)有关:如未加关键字virtual,则是普通的派生类中的新成员函数覆盖基类同名成员函数
(当然参数表必须一样,否则是重载),可称为同名覆盖函数,它不能实现运行时的多态性。

类的成员函数应尽可能地设置为虚函数,但必须注意以下几条:
{
1.派生类中定义虚函数必须与基类中的虚函数同名外,还必须同参数表,同返回类型。否则被认为是重载,而不是虚函数。
如基类中返回基类指针,派生类中返回派生类指针是允许的,这是一个例外。
2.只有类的成员函数才能说明为虚函数。这是因为虚函数仅适用于有继承关系的类对象。
3.静态成员函数,是所有同一类对象共有,不受限于某个对象,不能作为虚函数。
4.一个类对象的静态和动态类型是相同的,实现动态多态性时,必须使用基类类型的指针变量或引用,
使该指针指向该基类的不同派生类的对象,并通过该指针指向虚函数,才能实现动态的多态性。
5. 内联函数每个对象一个拷贝,无映射关系,不能作为虚函数。
6. 析构函数可定义为虚函数,构造函数不能定义虚函数,因为在调用构造函数时对象还没有完成实例化。
在基类中及其派生类中都动态分配的内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。
7. 函数执行速度要稍慢一些。为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,
函数的调用机制也是间接实现。所以多态性总是要付出一定代价,但通用性是一个更高的目标。
8. 如果定义放在类外,virtual只能加在函数声明前面,不能(再)加在函数定义前面。正确的定义必须不包括virtual。
}

对递归函数的内联扩展可能引起部分编译器的无穷编译。

内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,
用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);
也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),
从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,
因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。

实例化是指在面向对象的编程中,把用类创建对象的过程称为实例化。是将一个抽象的概念类,具体到该类实物的过程。
实例化过程中一般由类名 对象名 = new 类名(参数1,参数2…参数n)构成。

纯虚函数
纯虚函数(pure virtual function)是指被标明为不具体实现的虚拟成员函数。
它用于这样的情况:定义一个基类时,会遇到无法定义基类中虚函数的具体实现,其实现依赖于不同的派生类。

(比较)
定义纯虚函数的一般格式:
virtual 返回类型 函数名(参数表)=0;
虚基类(virtual base class)定义方式:
class 派生类名:virtual 访问限定符(/继承方式) 基类类名{…};
!!!!!!含有纯虚函数的基类是不能用来定义对象的。纯虚函数没有实现部分,不能产生对象,
所以含有纯虚函数的类是抽象类。
使用纯虚函数注意事项:
{
1 定义纯虚函数时,不能定义虚函数的实现部分。即使是函数体为空也不可以,函数体为空就可以执行,只是什么也不做就返回。
而纯虚函数不能调用。
2 “=0”表明程序员将不定义该函数,函数声明是为派生类保留一个位置。“=0”本质上是将指向函数体的指针定为NULL。
3 在派生类中必须有重新定义的纯虚函数的函数体,这样的派生类才能用来定义对象。
}
如果使用基类指针或引用指明派生类对象并使用该指针调用虚函数(成员选择符用箭头号“->”),
则程序动态地(运行时)选择该派生类的虚函数,称为动态联编。
动态联编(dynamic binding)亦称滞后联编(late binding),对应于静态联编(static binding)。
如果使用对象名和点成员选择运算符“.”引用特定的一个对象来调用虚函数,则被调用的虚函数是在编译时确定的(称为静态联编)
第二层指针,在实例化带虚函数的类(创建对象)时,编译器在对象前加上一个指向该类的虚函数表的指针。
第三层指针是链表结点类对象中指向抽象基类Object的指针(这也可以是引用,但本例是指针)。(没太懂)

按C++的常规,资源获取是由构造函数实现,而资源释放是由析构函数完成。
所以与内存动态分配一样,由文件重构对象放在构造函数中,把对象存入文件则放在析构函数中。

在编制程序时有一条惯例:把正常执行的程序与异常处理两部分分隔开来,这样使代码更易于跟随和维护。
!!!!!!一个函数try块把一组catch子句同一个函数体相关联。
如果函数体中的语句抛出一个异常,则考虑跟在函数体后面的处理代码来处理该异常。函数try块对构造函数尤其有用。

catch子句由三部分组成:关键字catch、圆括号中的异常声明以及复合语句中的一组语句。
catch子句不是函数,所以圆括号中不是形参,而是一个异常类型声明,可以是类型也可以是对象。
catch子句的使用:它只有一个子句,没有定义和调用之分。使用时由系统按规则自动在catch子句列表中匹配。
catch子句可以包含返回语句(return),也可不包含返回语句。
包含返回语句,则整个程序结束。而不包含返回语句,则执行catch列表之后的下一条语句。
catch子句异常声明中采用对象只是一种形式。甚至异常并非一个类对象时,也可以用同样的格式,
比如异常为一枚举量,这时就等效于按值传递,而不是调用类对象的公有成员
catch子句的异常声明与函数参数声明类似,可以是按值传送,也可以是按引用传递。
使用引用类型的异常声明,catch子句能够修改异常对象,但仅仅是异常对象本身,正常程序部分的量并不会被修改。
与一般类对象不同,实际上异常对象处理完后,生命期也就结束了。对大型类对象减少不必要的拷贝是很有意义的,
所以对于类类型的异常,其异常声明最好也是被声明为引用。

默认构造函数
{
1.没有值的构造函数
2.所有函数都有默认值的构造函数(不提倡)
}

如果类说明中没有给出构造函数,则C++编译器自动给出一个缺省的构造函数:
类名(void) {}
只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。
析构函数名与类名相同,但在前面加上字符‘~’,如
~CGoods()。
析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。
一个类有一个也只有一个析构函数,这与构造函数不同。析构函数可以缺省。
对象注销时,系统自动调用析构函数。

C++函数中参数的传递方式是传值。在函数域中为参数重新分配内存,而把实参的数值传递到新分配的内存中。
它的优点是有效避免函数的副作用。
引用主要用于函数之间的数据传递。定义的格式为:
类型 &引用变量名=已定义过的变量名;
例如:
double number ;
double &newnum=number ;
newnum是新定义的引用类型变量,它是变量number的别名。

const引用:引用在内部存放的是被引用对象的地址,不可寻址的值是不能引用的;
当引用作为形参时,实参也不能使用不可寻址的值,更不可能进行类型转换(如:实数转换为整数)。
但是const引用不同,它是只读的,为了绝对保证不会发生误改,编译器实现const引用时,生成一个临时对象,
引用实际上指向该临时对象,但用户不能访问它。所以const引用可以实现不可寻址的值(包括字面常量)的引用,例如:
double dval=1024; const int &ri=dval;
是正确的,编译器将其转换为:
double dval=1024; int temp=dval; const int &ri=temp;
因有临时对象,引用和类型转换都实现了。当const引用作为形参时,实参也能使用不可寻址的值,并能进行类型转换

同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。
这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。
在建立对象时可用同一类的另一个对象来初始化该对象,这时所用的构造函数称为拷贝构造函数(Copy Constructor)。
拷贝构造函数的参数——采用引用。如果把一个真实的类对象作为参数传递到拷贝构造函数,会引起无穷递归 。
系统会自动提供,称为缺省的按成员语义支持的拷贝构造函数,
每个类成员被依次拷贝,亦称为缺省的按成员初始化。
按成员作拷贝是通过依次拷贝每个数据成员实现的,而不是对整个类对象按位拷贝。
赋值运算符“=”称缺省的按成员拷贝赋值操作符,同类对象之间可以用“=”直接拷贝 。

通常按成员语义支持已经足够。
但在某些情况下,它对类与对象的安全性和处理的正确性还不够,
这时就要求类的设计者提供特殊的拷贝构造函数和拷贝赋值操作符的定义。

在类定义中如果没有显式给出构造函数时,并不是不用构造函数,而是由系统自动调用缺省的构造函数或缺省的拷贝构造函数。
如果有程序设计者定义的构造函数(包括拷贝构造函数),则按函数重载的规律,调用合适的构造函数。

拷贝构造函数还在另两个方面使用:

  1. 当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用。
    这时要在内存新建立一个局部对象,并把实参拷贝到新的对象中。
    2.当函数的返回值是类对象,函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。
    因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存,
    所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对象,
    该临时对象的生存周期只在函数调用处的表达式中。
    所谓return 对象,实际上是调用拷贝构造函数把该对象的值拷入临时对象。
    如果返回的是变量,处理过程类似,只是不调用构造函数。

类中的成员,除了成员数据和成员函数外,还有成员对象,用其他类的对象作为类的成员。
成员对象是实体,系统不仅为它分配内存,而且要进行初始化。
C++中对含对象成员的类对象的构造函数有特殊的格式:
类名::构造函数名(参数总表):对象成员1(参数表1),对象成员2(参数表2),……对象成员n(参数表n){……}
对成员对象初始化,必须调用该成员对象的构造函数来实现。
并且是首先依次自动调用各成员对象的构造函数,再使用类自己的构造函数。
冒号以后部分实际是函数体的一部分,所以在构造函数的声明中,冒号及冒号以后部分必须略去。
对于不同作用域的对象类型,构造函数和析构函数的调用如下:
{

  1. 对全局定义的对象,当程序进入入口函数main之前对象就已经定义,这时要调用构造函数。整个程序结束时调用析构函数。
  2. 对于局部定义的对象,每当程序控制流到达该对象定义处时,调用构造函数。当程序控制走出该局部域时,则调用析构函数。
  3. 对于静态局部定义的对象,在程序控制首次到达该对象定义处时,调用构造函数。当整个程序结束时调用析构函数。
    }

前置“++”格式为:
返回类型 类名::operator++(){……}
而后置“++”格式为:
返回类型 类名::operator++(int){……}

重载的运算符“+=”标准算法是:
Complex& Complex::operator +=(Complex & com){
real += com.real;
image += com.image;
return *this;
}

  1. 运算符重载函数的函数名必须为关键字Operator加一个合法的运算符。在调用该函数时,将右操作数作为函数的实参。
    2.  当用类的成员函数实现运算符的重载时,运算符重载函数的参数(当为双目运算符时)为一个或(当为单目运算符时)没有。
    运算符的左操作数一定是对象,因为重载的运算符是该对象的成员函数,而右操作数是该函数的参数。

由关键字static修饰说明的类成员,成为静态类成员(static class member)。
虽然使用static修饰说明,但与函数中的静态变量有明显差异。
类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。

静态数据是该类所有对象所共有的,可提供同一类的所有对象之间信息交换的捷径。
静态数据成员属于整个类,使用时可用以下格式:
类名::静态数据成员名

指针没有实体,利用运算符将指针和内存关联起来才可以用

在父类中是虚函数,子类无论继承多少次都是虚函数

<<不能重载为类的成员函数

数据独立,代码共享->节省空间

分配大小[ ]
初始化/赋值()

静态成员函数只能访问静态成员变量
动态成员函数可以访问所有成员变量(静态成员变量和动态成员变量)
静态成员函数有类没有对象(无动态成员)
{
动态是其自己的,可以访问
静态是共享的,也可访问
}

{
友元函数
其成员函数
}

在C++实现多态
{
引用
指针
}

new
delete
对于数组进行动态分配的格式为:
指针变量名=new 类型名[下标表达式];
Delete [ ] 指向该数组的指针变量名;
eg.
float(*cp) [30] [20]; //三级指针
float (*bp) [20]; //二级指针
cp=new float [1] [20] [30];
bp=new float [30] [20];
两个数组都是由600个浮点数组成,前者是只有一个元素的三维数组,每个元素为30行20列的二维数组,
而另一个是有30个元素的二维数组,每个元素为20个元素的一维数组。
删除这两个动态数组可用下式:
delete [] cp; //删除(释放)三维数组
delete [] bp; //删除(释放)二维数组

类内声明,内外实现(保密性)
encapsulation封装,胶囊
parameter参数,参变量
constructor构造函数
destructor析构函数
template模板
class类
array数组
heap堆

atoi(ascii to integer)

友元 引狼入室,破坏封装性

多态(实现角度)
{
编译时多态
运行时多态
}
new生成对象后要用delete释放空间
多态性->虚性
联编=编联=束定=绑定
静态联编->函数重载
动态联编->
类型和值的置换过程称为模板实例化 (template instantiation)

函数模板根据一组实际类型或(和)值构造出独立的函数的过程通常是隐式发生的,
称为模板实参推演(template argument deduction)
在main()函数中,由调用函数模板(functron template) 而生成的函数,称为模板函数(template function)
系统不检查数组边界
在类外定义的类模板中的成员函数必须是函数模板。这样的成员函数只有在被调用(或取地址)时才被实例化。
句柄是一个泛型(无类型)指针,指向包含了使用该对象有关信息的一块内存单元,这里有对象的地址还有其他有关的信息。
从逻辑上说它是一个对象的代号。
建立一个Windows对象,自然就建立起一个实例句柄。需要使一个句柄无效只须撤消对该对象的引用,不要销毁这个句柄。
堆区是不会自动在分配时做初始化的(包括清零),所以必须用初始化式(initializer)来显式初始化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值