- 关于拷贝构造函数,重载赋值运算符
A b = a;
此情况属于:一个对象(b)需要通过另外一个对象(a)进行初始化
这种情况需要利用拷贝构造函数,除此之外,还有两种情况需要调用拷贝构造函数
(1) 一个对象以值传递的方式传入函数体
(2)一个对象以值传递的方式从函数返回
A b;b=a;
此情况属于:定义了一个对象(b),然后调用后面重载的赋值函数
A *b = new A;
此时调用了构造函数,但是注意,这里的赋值运算符不是类中的赋值运算符,而是普通的赋值运算符;
如果定义一个指针或者引用,不会调用构造函数
拷贝构造函数没有返回值,拷贝构造函数的参数可以使一个或多个,但左起第一个必须是类的引用对象
-
关于scanf里的%xd
scanf(“%3d%f”,&x,&y);则会将输入的前3位数赋给x,输入中后面的部分将赋给y,
如输入12345□678↙,则x=123,y=45.000000。 -
double类型可以与int,float进行匹配
如果同时出现两种函数,会出现多个匹配 -
内联函数
一般可以用于加快程序执行速度,但是可能增加也可能减少可执行文件大小
构造函数可以是内联函数 -
sizeof和strlen
sizeof返回所占内存空间,strlen返回字符串长度
char *str1 = “Hello”,str2[] = “Hello”;
sizeof(str1)= 4
sizeof(str2)= 6
但是得注意八进制转义字符和十六进制转义字符
八进制字符的一般形式是’\ddd’,d是0-9的数字。十六进制字符的一般形式是’\xhh’,h是0-9或A-F内的一个
如strlen以下字符串,结果为
" 0123\0789 " 7 (0 ,1,2,3,\07,8,9)
" 0123\0123 " 6(0 ,1,2,3,\012,3)
" 0123\0889 " 4(0 ,1,2,3,\0)
-
计算结构体空间
注意#pragma pack(4)与8
每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行
注意点
1 先找有没有virtual 有的话就要建立虚函数表,+4
有virtual修饰的成员函数编译器会构建虚函数表,在该类的对象中会存放一个指向虚函数表的指针,
2 static作为静态变量是对类而言的,为所有对象共有 +0
3 神马成员都没有的类,或者只有成员函数 +1
4 对齐法则 -
函数指针的用法
C++指向函数的指针定义方式为:
返回类型 (*指针名) (函数参数列表) ,例如 void (*p)(int)是指向一个返回值为void 参数为int类型的函数
函数指针作为参数传递
int test(int a)
{
return a-1;
}
int test2(int (*fun)(int),int b)
{
int c = fun(10)+b;
return c;
}
int main(int argc, const char * argv[])
{
typedef int (*fp)(int a);
fp f = test;
cout<<test2(f, 1)<<endl; // 调用 test2 的时候,把test函数的地址作为参数传递给了 test2
return 0;
}
指向成员函数的指针有所不同
1非静态成员函数
定义方式:返回类型 (类名::*指针名)(函数参数列表)例如void (A::*p)(int)是一个指向A类中成员函数的函数指针。
赋值方式:p=&A::函数名,而一般的函数指针的赋值是p=函数名即可,注意区别。(成员函数必须是public类型的)
调用方式:成员函数指针的调用必须通过类对象进行调用,a.*p(int)即可调用成员函数(该成员函数是public类型的)
2静态成员函数
对于静态成员函数的定义和使用方法都与普通函数指针的相同,只是在赋值的时候和非静态成员们函数指针的赋值方法相同。
因为静态成员函数的指针类型是与普通函数指针类型相同的。
声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*
结果是int (*(*p)[10])(int *)
*p指向一个大小为10的数组,即(*p)[10]
2.*( *p)[10]表示*p指向一个大小为10的数组,且每个数组的元素为一个指针
- 堆与栈对比
栈是向低地址扩展的数据结构,是一块连续的内存的区域。在WINDOWS下,栈的大小是2M,能从栈获得的空间较小
堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储 的空闲内存地址的,堆获得的空间比较灵活,也比较大
函数中定义的局部变量是存在在栈区,动态生成的变量存在在堆区,由指针进行读写。
堆的效率不如栈。大量的new/delete会造成内存空间不连续
- new delete malloc free
https://blog.csdn.net/Hackbuteer1/article/details/6789164
- clase与struct区别
C++里:a.成员访问权限->class的成员访问权限为private,而struct的成员访问权限为public b.默认的继承方式->class的默认继承方式为private,而struct的默认继承方式为public
struct在C和C++之间的区别
a.c中,struct是用户自定义数据类型,而c++中,struct是抽象数据类型,支持成员定义函数
b.c中的struct是没有权限设置的,但是在c++中,给strcut添加了权限设置,增加了访问权限;
c.c中的struct只是变量的聚合体,可以封装数据,但是不可以隐藏,不可以定义函数成员;但是C++中的struct可以定义函数成员
-
不能被重载的运算符
. (成员访问运算符)
*星号 (成员指针访问运算符)
:: (域运算符)
sizeof (长度运算符)
?: (条件运算符) -
全局变量可不可以定义在可被多个.c文件包含的头文件中
如果不使用static,会报错
但是使用了static,可以定义,此时变为内部链接,此时所谓的全局变量相当于每个c文件的局部变量。即不会相互影响。 -
构造函数与析构函数
构造函数在创建对象的时候调用,先调用父类,再子类,析构相反
1)当父类的指针new一个子类的对象时,
父类析构不是虚析构,则delete的时候不调用子类的,只是调用父类的析构函数,如果是virtual的析构函数,则先子类之后父类
2)当子类的指针new一个子类的对象时,构造析构都会调用父类
A *a = new C();是调用父类的指针new一个子类的对象
即:A B C deA
若A中的析构函数是virtual,则A B C deC deB deA
B *b = new C(); 即:A B C deB
若B中的析构函数是virtual,则A B C deC deB deA
C *c = new C();子类的指针new一个子类的对象,先构造(父->子)后析构(子->父)
结果A B C deC deB deA
- 继承
基类public成员, 在子类中仍然是public成员,在子类中可以使用, 在子类的对象中也可以调用
基类的protected成员,在子类中仍然是protected成员,在子类中可以使用,在子类的对象中不能直接调用
private成员,只能在基类中使用,在基类对象,子类,子类对象中都不能使用
其他:
1.char a =’\82’;
因为有一个8,显然已经不是八进制,实际上就’\82’中包含3个字符,分别是‘\’,‘8’,‘2’,会将最后一个字符赋值给表达式的值,赋值时是将字符’2’给了a
2.递归
时间复杂度:递归次数
空 间复杂度:递归深度(调用栈帧)
3.头文件作用
Stdio输入输出,stdlib数值转换,内存分配,srdarg可变参数
4.C++不属于类型安全,因为可以进行强制类型转换
5.setbase将数字转换为 n 进制,既可用于输入,也可用于输出
以下均是输出
setw(n)用法: 通俗地讲就是预设宽度
setfill(char c) 在预设宽度中如果已存在没用完的宽度大小,则用设置的字符c填充
setprecision(n)可控制输出流显示浮点数的数字个数
6.(int &)a
float a=1;
(int &)a 是告诉编译器将a看成int对待(不做任何转换),所以(int &)a值为1065353216.
(int&)a 相当于*(int*)&a ,*(int*)(&a),*((int*)&a)
7.c语言默认返回类型int