C++介绍

本贾尼.斯特劳斯特卢普,于1979年在贝尔实验室负责分析UNIX系统内核流量的分布情况时,特别希望有一种更加模块化的工具,于1979.10开始着手研发一款新的编程语言,在C语言的基础上增加了面向对象的机制,也就是C++,1983年完成了C++的第一个版本

一、C++与C的关联与重要区别:

  1. C++完全兼容C语言的所有内容

  2. 支持面向对象的编程思想

  3. 支持运算符重载、函数重载的编译时多态机制

  4. 泛型编程、模板编程

  5. 支持异常处理

  6. 类型检查更加严格

注意:学习C++目前重点学习的是面向对象的编程思想,而不是各种花里胡哨的语法

二、第一个C++程序

#include <iostream>
using namespace std;

int main(int argc, const char* argv[])
{
    cout << "Hello World!" << endl;
    return 0;
}
  1. 文件扩展名由 .c 变成.cpp .cc .C .cxx

  2. 编译器由gcc变成g++,gcc也可以继续使用,需要增加编译参数

-xC++ -lstdc++
  1. C++语言的标准头文件不带.h,iostream意为in out stream,在C++中输入、输出被封装成了流操作,C语言头文件还可以继续使用,但是标准C的头文件建议名字换成前面加c 后缀去掉的新名字 例如:cstdio,为了删除原C标准头文件中的大量的宏,重新放入名字空间中,防止命名冲突

  2. C++输入、输出
    cout 用于输出
    cin 用于输入
    不需要占位符,会自动识别数据类型
    printf/scanf 属于C标准库函数
    cout/cin 是C++标准库中的类对象

  3. 增加了名字空间机制,是C++为了解决命名冲突而发明的一项机制

三、C++与C数据类型的不同

1、结构的不同

①不再需要通过typedef来缩短结构类型名,在C++中设计好结构后,定义结构类型时不再需要使用struct关键字

struct Student
{
    char name[20];
    char sex;
    char id; 
};

int main(int argc, const char* argv[])
{
    Student stu;
}

②结构中可以有成员是成员函数、成员变量,结构变量、结构指针使用 . 和 -> 访问成员,如果是成员函数可以直接访问同结构中的任何成员,不需要 . 和 ->

struct Student
{
    char name[20];
    char sex;
    char id;
    void func(int num)
    {
        cout << "我是Student的成员函数" << num << " " << id << endl;
    }
};

int main(int argc, const char* argv[])
{
    Student stu;
    stu.id  = 10086;
    stu.func(100);
}

③结构中有一些隐藏的成员函数:构造函数、析构函数、拷贝构造、赋值操作

④结构可以继承其它结构,也可以被其他结构所继承

⑤可以给成员赋予访问控制属性

属性名范围
public公开的(默认的)
protected保护的(结构内和继承了它的结构中能使用)
private私有的(只有结构中才能使用)
2、联合的不同

①不再需要通过typedef来缩短联合类型名,在C++中设计好联合后,定义联合类型时不再需要使用union关键字

②联合中可以有成员是成员函数、成员变量,联合变量、联合指针使用 . 和 -> 访问成员,如果是成员函数可以直接访问同联合中的任何成员,不需要 . 和 ->

③联合中有一些隐藏的成员函数:构造函数、析构函数、拷贝构造、赋值操作

④可以给成员赋予访问控制属性

属性名范围
public公开的(默认的)
protected保护的(联合内能使用)
private私有的(只有联合中才能使用)
3、枚举的不同

①不再需要通过typedef来缩短枚举类型名,在C++中设计好枚举后,定义枚举类型时不再需要使用enum关键字

②C++编译器会对枚举的值进行检查,如果不符合就报错

enum Key{UP=183, DOWN, RIGHT, LEFT};

int main(int argc, const char* argv[])
{
    //Key k = 183;  //  false;
    Key k = UP;
}

③C语言使用整型来模拟的,C++中的枚举类型是一种真正的数据类型,所以不能与整型进行隐式类型转换了

4、bool类型

①C++中有真正的布尔类型,bool、true、false是C++的关键字,不再需要包含 stdbool.h 头文件

②true、false在C++中是1字节,而C语言是4字节(int)

注意:无论C还是C++,bool类型变量只能存储0|1

5、字符串的不同

①C++中的字符串被封装成了string类,可以与C语言的字符串进行转换

②string类被封装在string文件,并属于std名字空间,但是string已经被iostream包含

③使用string类,可以通过运算符的方式直接操作字符串,但是C语言string.h中的str系列函数也可以继续使用

运算符对应的str函数
=strcpy
+=strcat
==strcmp(相同为真)
size() \ length()strlen(只算字符个数)

④C++中没有规定string类必须以’\0’结尾,编译器在实现时在结尾加上’\0’也可以不加,由编译器决定,因为string是一个类,它的长度信息已经被封装记录在私有成员变量中了

6、void*的不同

在C语言中,void*类型可以与任意类型的指针进行自动转换

在C++中,void*类型不可以自动转换成其他任意类型的指针,如果需要把void *类型的指针赋值给其他类型的指针时,必须通过强制类型转换后才能赋值,为了提高指针数据类型的安全性

但是其他类型的指针还是可以自动转换成void*类型的指针,因为C语言标准库、系统函数中采用了大量的void *类型作为参数,如果不保留这个方式会导致C++在调用这些函数时非常麻烦

int* p = (int*)malloc(4);
void* p1 = p;

四、名字空间

1、为什么要名字空间

由于C++是完全兼容C语言,C++标准库中自带大量的类、函数、宏,而且还支持继承语法,导致全局的标识符大量增加,因此命名冲突的概率极大的增加,因此名字空间就是为了解决命名冲突

2、什么是名字空间

是C++中一种对命名空间进行逻辑划分的一种技术

namespace xxx
{
	变量;
    函数;
    结构、联合、枚举;
    类;
    ...
}

定义了名字空间后形成了一个相对封闭的作用域空间

3、如何使用

①直接导入

using namespace xxx;

之后就可以直接使用名字空间中的所有内容,虽然方便,实际工作中不建议

②域限定符 ::

XXX::标识符
4、名字空间可合并

名字空间可以被多次定义,不同位置的名字空间编译器会在编译时自动合并

a.cpp
namespace n1{int a;}
b.cpp
namespace n1{int b;}
main.cpp
using namespace n1;//  会把a、b都导入进来
5、名字空间中的声明和定义可以分开
a.h
namespace n1{
	extern int num;
}
a.cpp
int n1::num;

注意:可以分开定义,但是必须加上 名字空间名::变量名

6、匿名名字空间

所有全局的标识符都归属于同一个名字空间,称为匿名名字空间,可以通过 :: 全局标识符来指定访问匿名名字空间的内容

例如:同名的全局变量被同名的局部变量屏蔽后,可以以此指定访问全局变量

#include <iostream>
using namespace std;

int num = 50;

int main(int argc,const char* argv[])
{
	int num = 10;	
	cout << ::num << endl;	
}
7、名字空间可以嵌套
namespace n1{
	int num = 10;
	namespace n2{
		int num = 20;
		namespace n3{
			int num = 30;	
		}
	}
}

①采用逐层分解来访问

n1::n2::n3::num

②导入指定层的名字空间

using namespace n1::n2;
  1. 可以给名字空间的名字取别名
namespace n123 = n1::n2::n3

五、C++的堆内存管理

C++中有专门用于管理堆内存的语句,而C语言中只能使用标准库提供的函数

1、语法格式:
类型* p = new 类型名;

new:分配内存,相当于C语言的malloc

delete p;

delete:释放内存,相当于C语言的free

2、new允许在分配内存时直接初始化内存
//	类型* p = new 类型名(val);
int* p = new int(10);
3、new/delete 不能与 malloc/free 混合使用
int* p = new int;
free(p);

虽然语法允许,但是不能这样混合使用

因为使用new分配内存时,会自动调用结构、联合、类类型的构造函数,使用delete释放内存时,会自动调用结构、联合、类类型的析构函数

但是malloc和free都不会调用,如果混用,就会导致构造、析构没有对应调用

4、连续的内存的申请和释放
//	类型* p = new 类型名[个数];
int* p = new int[10];	//	十个int类型的连续堆内存
//	new[] 会多次调用构造函数

delete[] p;	//	delete[]专门用于释放通过 new[] 申请出来的内存
//	delete[]也会多次调用析构函数

注意:malloc/free new/delete new[]/delete[] 都不能混用

注意:通过new[]为结构、联合、类类型申请的内存的前4个字节中记录了申请的次数,这样就可以让编译器知道需要调用多少次构造函数和析构函数

5、重复释放问题

delete可以释放空指针,但是也不能重复释放其他有效地址,与free一致

6、内存分配失败

malloc分配内存失败会返回NULL

new分配内存失败会抛出一个异常std::bad_array_new_length,如果不接异常并处理,那么会终止

7、返回值类型

malloc返回void *类型的指针

new返回一个对应类型的指针

malloc/free 和 new/delete 的区别?

区别malloc/freenew/delete
身份函数关键字/运算符
返回值void*对应类型的指针
参数字节个数(手动计算)类型(自动计算)
连续内存手动计算总字节数new[个数]
扩容realloc无法直接处理
失败NULL抛异常
构造\析构不调用调用
初始化不能初始化可以初始化
头文件stdlib.h不需要
函数重载不允许重载允许重载
内存分配的位置堆内存自由存储区

注意:自由存储区是一个抽象的概念,而不是具体某个位置段,平时一般称new是分配在堆内存也问题不大,因为new底层默认调用了malloc,所以此时称分配在堆内存没问题,但是new可以像运算符一样被程序员重载或借助 new(地址) 类型 两种方式分配内存时,可以分配到其他内存段,所以称为自由存储区

现在有一块已经分配好的内存(堆、栈) 如何让通过new新申请的类对象、结构变量使用这块内存

#include <iostream>
using namespace std;

struct Student
{
	char name[20];
	char sex;
	int id;

	Student()
	{
		cout << "我是构造函数" << endl;	
	}
};

int main(int argc,const char* argv[])
{
	cout << sizeof(Student) << endl;
	char arr[28] = {};
	Student* stu = new(arr) Student;
	cout << &arr << " " << stu << endl;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值