1.C编译器不允许在struct内部定义成员函数,C++编译器则可以
C++编译器定义的结构体和类的区别:结构体内部成员(数据和方法)都只能是公有的而class则默认是私有的
2.系统提供的默认构造函数是不带任何参数的,只生成对象并不进行数据成员的初始化操作
class test
{
private:
int a;
int b;
public:
void output()
{
cout<<"a"<<a<<endl;
cout<<"b"<<b<<endl;
}
}; //输出结果是-58993460,-58993460两个随机数
3.如何查看是否在程序中发生内存泄露?系统自定义的析构函数是否会释放指针成员指向的内存空间?
3.1通过使用工具插件BoundsChecker可以有效进行查看
3.2构函数只是释放定义的成员变量,不会释放指针成员指向的空间,需要手动在析构函数释放
4.关于继承类的构造函数,在子类实例化对象会先调用父类的构造函数,如果父类的构造函数有参数,则必须在子类的构造函数进行初始化
5. C++规定在类中初始化常量和引用必须使用初始化列表
6.而冒号初始化与函数体初始化的区别在于:
冒号初始化是给数据成员分配内存空间时就进行初始化,就是说分配一个数据成员只要冒号后有此数据成员的赋值表达式(此表达式必须是括号赋值表达式),那么分配了内存空间后在进入函数体之前给数据成员赋值,就是说初始化这个数据成员此时函数体还未执行。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/chm_study/c.bmp)
6.类内部函数重载的条件?
函数的参数个数或类型不同(返回值不同以及缺省函数参数情况要注意),也就是编译器根据你提供的条件能知道要加载那个函数
第一种情况:
(1)void output();
(2)int output();
第二种情况:
(1)void output(int a,int b=5);
(2)void output(int a);
以上两种是典型的重载错误
7.数据类型转换的条件:
数据的内存模型是相同的,如int与char,作为强制类型转换只可能丢失数据,但是可以转换,而int型和一个对象数据类型是不能进行类型转换的
字类指针可以转换为父类,父类不能转换为字类
8.C++多态性
接上例:
定义一全局函数:
void global_breath(animal *pb)
{
pb->breath();
}
调用时:
fish fs;
animal *pa;
pa = &fs;
global_breath(pa); //输出是animal breath;由于fish是从animal继承的,因此内存首地址是相同的,系统先通过隐式转换将fish转换成animal类型指针
//pa实际上和&fs都是指向内存的首地址,因此先调用animal
如果animal成员函数是virtual breath();那么此时输出的就是fish breath,由于c++编译器的多态性,编译器将根据参数的类型进行绑定
注意:由于fish是继承了animal,因此有更多的数据成员,在做类型转换的时候可以将fish转换成animal,这样只是损失部分数据,但不能将animal转换成fish,内存模型不匹配
9.C++引用与指针的区别
int a = 9;
int &b = a; //b作为a的引用,引用在定义时必须赋初值
int *pa = &a; //引用相当于变量a的别名,不占用新的内存空间,pa则需要内存空间来保存a的地址
主要用于函数参数的传递,例如change(int &a, int &b);用于改变a,和b的值
10.类定义的头文件也可以包含父类的头文件,并非只是cpp文件包含.h的头文件
11.virtual在子类不需要加上,子类函数依然还是虚函数。
12.cpp文件参与编译,.h文件不参与编译,.cpp文件单独编译,生成.obj文件,link(连接lib)生成.exe文件