C++基础 一

来源:互联网 发布:java md5怎么解密 编辑:程序博客网 时间:2024/05/17 08:18
new---delete---malloc----free关系:

malloc/free是库函数.不在编译器控制权限之内,有些任务不能执行 ----free只会释放内存
new/delete是运算符 ,它们可以动态申请内存和释放内存,在对象创建同时自动构造,消亡前自动析构 ---delete会调用对象的析构函数

delete与delete[]区别:

delete只调用一次析构函数--删除一个指针
delete[]会调用每一个成员的析构函数--删除一个数组

C++有哪些性质 (面向对象特点):
封装,继承 多态

子类析构时会调用父类的析构函数吗:

析构函数调用的次序是先派生类的析构在基类的析构
就是在基类的析构调用的时候 派生类信息已经全部销毁
定义一个对象时先调用基类的构造在调用派生类的构造
析构却恰恰相反
   
多态,虚函数 纯虚函数

多态(可扩展):
父类指针指向子类对象-----如果以一个基础类指针指向一个衍生类对象(派生类对象)
                         那么经由该指针只能访问基础类定义的函数
有集成      虚函数重写
一个对象多种实现  就是不同对象接收相同信息时产生不同的动作

C++编译器如何实现多态:
1--提前布局 vptr指针和虚函数表
2--发生多态的时候 base->vptr->虚函数 (函数的入口地址)

函数指针做函数参数(回调函数)

面向过程编程  C语言
间接赋值成立的三个条件
1--定义一个实参和形参
2--建立关联 实参取地址 给形参
3--*p=10

C语言 两个模型
1--(内存四区模型 函数调用模型)

C++ 和C语言的代码 是不一样
搭建一个舞台 让对象唱戏

虚函数:
在基类中以关键字virtual的成员函数
他提供了一种借口界面
允许在派生类中对基类的虚函数重新定义

纯虚函数:
在基类中为派生类保留一个函数的名字,以便派生类根据需要对它进行定义,作为接口而存在
纯虚函数不具备函数功能,一般不能直接被调用
重基类继承来的虚函数,在派生类中仍是虚函数,如果一个类中至少有一个纯虚函数
那么这个类被称为抽象类
抽象类中不仅包括纯虚函数,野包括虚函数,抽象类必须用作派生其他类的基类,
而不能用于直接创建对象实例,可以使用指向抽象类的指针实现多态性

什么是引用 申明和使用引用需要注意哪些问题:

引用就是某个目标变量的别名
引用必须初始化
不能建立数组的引用
不能把该引用名作为其他变量的别名

将 引用 作为函数参数有哪些特点
1--传递引用给函数与传递指针的效果是一样的
  被调函数的形参成为主调函数中实参的一个别名
  在被调函数中对形参变量操作就是对相应的目标对象(主调函数)的操作
2--使用引用传递参数,在内存中没有产生实参的副本,而是直接对实参操作
  使用一般变量传递函数,会分配存储单元,形参变量是实参变量的副本
  如果传递对象,还会调用拷贝构造函数,所以数据较大时 用引用效率更高

在什么时候使用 常引用
如果想利用引用提高程序效率,又不想数据被改变 就应该使用常引用
const类型标识符 &引用名=目标变量名
const int &ra=a;

将引用 作为函数返回值 好处 ,规则
好处 : 在内存中不产生返回值副本

规则:
1--不能返回局部变量的引用 ---局部变量会在函数返回后被销毁
2--不能返回函数内部new分配内存的应用--函数返回的引用只是一个临时变量,不是实际变量
   引用所指向的空间 (new分配)无法进行释放

结构体个联合体有什么区别:
1--结构和联合是由不同的数据类型成员组成
在任何同一时刻,联合体中只放了一个被选中的成员(所以成员共有一块地址空间)
而结构体的所有成员都存在(不同成员的存放地址不同)
2--对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了
   而对于结构的不同成员赋值是互不影响的

 int  a=4;

int  &f(int  x)

{    a=a+x;

      return  a;

}

int main(void)

{    int   t=5;

     cout<<f(t)<<endl;  a = 9

    f(t)=20;             a = 20

    cout<<f(t)<<endl;     t = 5,a = 20  a = 25

     t=f(t);                a = 30 t = 30

    cout<<f(t)<<endl;  }    t = 60

}

重载和重写的区别:
重载:是指允许存在多个同名函数,而这些函数的参数表不同
(参数个数不同,参数类型不同,或两者都不同)

--编译器根据函数不同的参数表,对同名函数的名称做修饰
然后这些同名函数就成了不同的函数,对函数的调用编译器早已经确定了 (重载与多态无关)

重写:是指子类重新定义父类虚函数的方法

--和多态相关,当子类重新定义了父类的虚函数后,父类指针赋给它不同的 子类指针
动态调用属于子类的函数,这样的函数调用 在编译期间无法确定
(调用子类虚函数的地址无法给出)因此函数地址是在运行期绑定的

C++是不是类型安全:
不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的

main 函数执行以前,还会执行什么代码:
全局对象的构造函数会在main 函数之前执行

描述内存分配方式以及它们的区别:
1) 从静态存储区域分配。内存在程序编译时分配好,
这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,
函数执行结束时这些存储单元自动被释放。栈内存分配运算 内置于处理器的指令集。

3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,
程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定

请说出const与#define 相比,有何优点:

1)const有数据类型,宏没有
 编译器会对类型进行检查 宏只会替换字符
 const可调试  宏不可以

简述数组与指针的区别:
数组在栈上创建 ,指针在内存中

修改内容差别
char a[] = “hello”;

a[0] = ‘X’;

char *p = “world”; // 注意p 指向常量字符串

p[0] = ‘X’; // 编译器不能发现该错误,运行时错误

sizeof(a)计算数组容量(字节数) sizeof(p)是指针的字节数

当数组作为函数参数传递时,数组会退化为同类型的指针

char a[] = "hello world";

char *p = a;

cout<< sizeof(a) << endl; // 12 字节

cout<< sizeof(p) << endl; // 4 字节

计算数组和指针的内存容量

void Func(char a[100])

{

cout<< sizeof(a) << endl; // 4 字节而不是100 字节

}

int (*s[10])(int) 表示的是什么?

int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。

int id[sizeof(unsigned long)];这个对吗?为什么?

正确 这个 sizeof是编译时运算符,编译时就确定了  ,可以看成和机器有关的常量。

引用与指针有什么区别?

1) 引用必须被初始化,指针不必。

2) 引用初始化以后不能被改变,指针可以改变所指的对象。

3) 不存在指向空值的引用,但是存在指向空值的指针

复杂声明
void * ( * (*fp1)(int))[10];

float (*(* fp2)(int,int,int))(int);

int (* ( * fp3)())[10]();

分别表示什么意思?
【标准答案】                                                           
1.void * ( * (*fp1)(int))[10];   fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。

2.float (*(* fp2)(int,int,int))(int);   fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。

3.int (* ( * fp3)())[10]();   fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型

基类的析构函数不是虚函数,会带来什么问题?
派生类的析构函数用不上,会造成资源的泄漏

全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的:

生命周期不同:

全局变量随主程序创建和创建,随主程序销毁而销毁;局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在;

使用方式不同:通过声明后全局变量程序的各个部分都可以用到;局部变量只能在局部使用;分配在栈区。

操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里面


本篇属于整理文章----借鉴许多

有待完善--谢谢



0 0
原创粉丝点击