c++核心编程
即面向对象编程
面向对象由原来的程序等于数据结构+算法转变为对象等于数据结构+算法
而程序等于对象+对象+…消息
消息是对对象的控制
内存分区模型
c++程序在执行时,内存分为4大区
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量与静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数参数值,局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
意义:
不同区域存放的数据,赋予不同的生命周期,更*灵活
程序运行前
程序编译后,生成exe可执行文件,未执行该程序前分为两个区域
代码区:
存放cpu执行的机器指令(二进制代码)
特点:
1. 共享:目的在于频繁执行的程序,只要在内存中有一份代码即可
2. 只读:目的在于防止程序意外修改了它的指令
全局区
全局变量与静态变量存放于此
还包含常量区,有字符串常量与其他常量存放于此
该区域的数据在程序结束后由操作系统释放
# include
#include
using namespace std;
//全局变量
//函数体外,g--global
int g_a = 10;
int g_b = 10;
const int c_g_a = 10;
const int c_g_b = 10;
int main()
{
//创建普通变量
//只要变量写在函数体中,(main也算),就算普通变量
int a = 10;
int b = 10;
cout << "a地址" << &a << endl;
cout << "b地址" << &b << endl;
//a地址0x70fe1c
//b地址0x70fe18//相差4
cout << "g_a地址" << &g_a << endl;
cout << "g_b地址" << &g_b << endl;
//g_a地址0x472010
//g_b地址0x472014//相差4
//然而全局与局部的地址开头部分相差很大,说明两者不在一个内存区
//静态变量 在普通变量前加static
static int s_a = 10;
static int s_b = 10;
cout << "s_a地址" << &s_a << endl;
cout << "s_b地址" << &s_b << endl;
//s_a地址0x472018
//s_b地址0x47201c
//由此看出静态与全局内存紧挨在一起分配
//常量
//字符串常量
cout << "字符串常量地址" << &"hello world" << endl;
//字符串常量地址0x48803b
//与静态和全局有一定距离,但并不远
//const修饰变量
//1.const修饰全局变量,全局区
cout << "c_g_a地址" << &c_g_a << endl;
cout << "c_g_b地址" << &c_g_b << endl;
//c_g_a地址0x488064
//c_g_b地址0x488068
//与字符串常量很近,但还是有一定距离
//2.const修饰局部变量,不在全局区(带局部都不在全局区里)
const int c_l_a = 10;//local
const int c_l_b = 10;
cout << "c_l_a地址" << &c_l_a << endl;
cout << "c_l_b地址" << &c_l_b << endl;
//c_l_a地址0x70fe14
//c_l_b地址0x70fe10
system("pause");
return 0;
}
程序运行后
栈区:
由编译器自动分配释放,存放函数参数值,局部变量等
注意:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
# include
using namespace std;
int * func()
{
int a = 10;
return &a;
}
int main()
{
int * p = func();
cout << *p << endl;//[Warning] address of local variable 'a' returned [-Wreturn-local-addr]
cout << *p << endl;//只保留一次,第二次为乱值
system("pause");
return 0;
}
堆区
new在堆区开辟
new操作符
new int [5];//开辟整型数组
new int(100);//开辟一个整型空间,初值为100
int * p = new int [5];//new 返回的是指针
delete [] p;释放p指向的空间即new int [5];
类
定义类与对象
类是对象的抽象,而对象是类的实例
类与结构体很多性质相似
类可以看作一种数据类型,而对象就是变量
形式:
class 类名:
{
private:
私有的数据和成员函数;
public:
公有的数据和成员函数;//即接口
}
private是私有的,public是公有的,默认私有
类外定义函数是一种好习惯
格式:返回类型 类名 ::函数名(参数)::表示作用域
对于类中一些简单的成员函数可以用inline将其作为内置函数,减少调用时间,inline写在返回类型前面,就将main函数中的函数调用语句直接替换为函数语句
一个对象所占用的空间只与其数据成员所占据的空间相关
成员函数不占用存储空间,不同的对象使用的是同一段代码
类与对象的使用
构造函数实现数据成员初始化
构造函数与类同名,不具有任何类型,不返回任何值,在建立对象时对数据成员赋初值,不能被用户调用
类名()
{
}
可以用一个类对象,初始化另一个类对象,而不调用构造函数。
带参数的构造函数,在定义对象的时候给出实参
也可以
类名 :: 构造函数名(形参1,形参2,…):成员初始化{};
对于数组要在函数体中进行操作
在声明构造函数时还可以指定默认值
析构函数
是在撤销对象占用的内存前完成一些清理操作
-类名
是用户最后一次使用对象后的操作,(释放前),先释放的,先执
类的时候用**::,对象的时候用.**
指向成员函数的指针
数据类型名 (类名 :: * 指针变量名 )(参数表)//括号不可省略
指针变量名 = & 类名 :: 成员函数名
复制构造函数
类名 对象2(对象1)