c++基础复习(4)

复习点:一、strlen和sizeof   二、strcpy和memcpy  三、构造函数  四、深拷贝和浅拷贝 五、程序的编译过程  六、c和c++的区别         七、explicli

一、strlen和sizeof

(1)strlen是库函数;而sizeof是运算符。

(2)strlen操作的对象只能是字符指针;而sizeof则支持全部的类型,包括类。

(3)strlen在运行时遇'\0'终止,返回字符串长度(不包括'\0'),如何字符串中不包含'\0'就会导致返回值错误;而sizeof则是返回该变量的空间大小。

char str[] = "\0assd";
cout << strlen(str) << endl;
cout << sizeof(str) << endl;

(4)当参数为指针时,strlen可以计算出数组的大小;只能计算出指针空间大小。 

char *str = "assdssw";
cout << "strlen=" << strlen(str) << endl;
cout << "sizeof=" << sizeof(str) << endl;

 (5)strlen计算的是字符串实际大小;而sizeof计算的是该字符串所占的空间大小(之所以会大1,是因为字符串在定义会自动在结尾加上'\0')。

char str1[] = "assdssw";
cout << "strlen str1=" << strlen(str1) << endl;
cout << "sizeof str1=" << sizeof(str1) << endl;
char str2[20] = "abcdef";
cout << "strlen str2=" << strlen(str2) << endl;
cout << "sizeof str2=" << sizeof(str2) << endl;

二、strcpy和memcpy

char* strcpy(char* tarStr,const char* sourStr);
void* memcpy(void* tar,const void* sour,size_t len);

 (1)strcpy只能拷贝字符串;而memcpy可以拷贝任何类型的数据。

(2)strcpy在拷贝时不需要指定拷贝的大小,遇'\0'自动结束,容易溢出;而么memcpy在拷贝时需要指定拷贝空间的大小。

三、构造函数

1、构造函数的作用:在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。

每个类中都有自己的构造函数,就算程序中没有写构造函数,系统也会为其分配一个默认的构造函数。构造函数执行的顺序:

(1)传参 (2)构造成员变量 (3)成员初始化列表 (4)执行构造函数体

无论是在构造成员变量时还是在成员初始化列表中,在初始化是,都是按照类中的出现顺序进行的。

为什么会有成员初始化列表:

(1)类中成员变量存在const变量,const变量只能初始化不能赋值;而在构造函数体中,执行的过程属于赋值;而在成员初始化列表中的过程属于初始化。

(2)派生类在实例化对象时,会先调用基类的构造函数,先去构造基类中的成员变量,那么派生类如何将基类需要的参数传递给基类那,就是通过成员初始化列表(基类的函数体,执行在派生的函数体之前)。

2、拷贝构造函数(复制构造函数)

在构造函数中有一种特殊的构造函数名为:拷贝构造函数又被称为复制构造函数。它的作用是:使用一个已经存在的对象(由拷贝构造函数的参数指定),去初始化同类的一个新对象,拷贝构造函数的参数一般为对象的引用

拷贝构造函数被调用的三种情况:

(1)当用类的一个对象去初始化该类的另一个对象时,会调用拷贝构造函数。

(2)如果函数的形参是类的对象引用或对象,调用函数时,进行形参和实参结合时,会调用拷贝构造函数。所以这里需要注意:当构造函数的形参为对象时,会造成无限递归,导致程序崩溃。

(3)如果函数的返回值时类的对象,函数执行完后返回调用者时,会调用拷贝构造函数。

一般如果用户程序中没有写拷贝构造函数,系统会为其分配一个默认的拷贝构造函数,但系统的分配的只能简单的完成一个初始化的任务,这样很容易造成浅拷贝,如果类的成员变量中有new或mallc申请的空间的,那么浅拷贝就会导致程序崩溃。

四、深拷贝和浅拷贝

#include <iostream>
using namespace std;
class Test
{
public:
	Test()
	{
		str = new char[20]();
		cout << "空间申请成功" << endl;
	}
	~Test()
	{
		delete [] str;
		str = NULL;
		cout << "空间已被释放" << endl;
	}
	char *str;
};
int main()
{
	Test test1;
	Test test2(test1);//使用已有对象初始化该类的对象是会触发拷贝构造函数
	return 0;
}

上面的程序会崩溃的原因是:同一块空间被释放了两次。那么为什么会造成这种情况那?上面说过:在使用已有对象初始化该类的对象是会触发拷贝构造函数,而上面的代码中,并没有拷贝构造函数,这样就会自动触发系统的拷贝构造的函数,而系统默认的拷贝构造函数就是简单的赋值,所以就会导致test2对象的str成员变量和test1对像的成员变量str共用了一块空间,这就是浅拷贝,而在释放时test1和test2需要调用各自析构函数,就会导致同一块空间被连续释放两次,导致程序崩溃。

那么该如何解决这一问题那?

即在拷贝构造构造函数为新的对象也分配空间(深拷贝),那么这就不能使用系统默认的函数了,需要自己写一个拷贝构造函数。

Test(const Test& t)
{
        str = new char[20]();
        cout << "拷贝:空间申请成功" << endl;
}

浅拷贝:在使用已有对象初始化该类的对象时,新的对象和已有对象公用了一个实体(一块空间)。存在问题:引起内存二次释放,导致程序崩溃。

深拷贝:在使用已有对像初始化该类的对象时,在拷贝构造函数为新的对象分配空间并将已有对象的数据为新对象拷贝一份(俩份空间)。

五、程序的编译过程

机器是识别不了高级语言的,需要在编译过程中将高级语言转化为机器可以识别的机器语言。

(1)预处理过程:展开头文件,替换宏等,即处理#开头的。还有去掉注释,增加行号等。

(2)编译过程:将预处理生成的.i文件由高级语言转为汇编语言。

(3)汇编过程:将汇编语言在转化为机器语言。

(4)链接过程:链接程序在执行过程中需要的库。

六、c和c++的区别

(1)c是经典的面向过程的语言;而c++实在c的基础上发展的面向对象的语言。

(2)c语言关注的是这个问题,具体该用什么方法解决;而c++关注的是如何将事件抽象为一个类。

 (3)c++中增加了新的特性:函数的封装、继承、多态等。

(4)c++增加了一些安全性机制。

七、explicli

用于显示申明只有一个参数的构造函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值