c++面向对象概述、内存分析、引用、函数

简介: c++面向对象概述、内存分析、引用、函数

1.c++内存分区模型

c++程序在运行的过程中,内存会被划分为以下四个分区

代码区:程序的所有程序的二进制代码,包括注释会被放到此区

全局区:存放静态变量、全局变量、常量(字符串常量和const修饰的常量),此区的数据将在程序结束后由操作系统释放

using namespace std;
//不在任何函数内的变量是全局变量
int a = 10;
int b = 23;
 
int main() {
  //在某个函数内的变量
  int c = 12;
  cout << (int)&a << endl;
  cout << (int)&b << endl;
  cout << (int)&c << endl;
 
}

栈区:用于存放局部变量、函数参数等,是由编译器自动释放和分配,所以不能让栈区返回一个地址,

#include <iostream>
#include <string>
using namespace std;
 
int* f() {
  int a = 10;
  return &a;//栈区不要返回地址。局部变量是由编译器自动释放和分配
}
int main() {
  
  int* p = f();
  cout << *p;//10 第一次编译器会做保留
  cout << *p;//不会打印10
}

堆区:存储对象(使用new操作符,后面会介绍)由程序员分配释放,若我们不释放,程序结束由操作系统释放

c++中通过new关键字将数据开辟到堆区

#include <iostream>
using namespace std;
int* f() {
  /*
  *1.指针本身也是局部变量,存放在栈长中,但是保存的数据在堆中
  2.new关键字开辟一块堆区,返回的是该数据类型的指针
  */
  int *a = new int(10);
  return a;
}
int main() {
  int* p = f();
  cout << *p;//10
  cout << *p;//10
  //3.堆区的数据程,序员可以通过该delete释放
  delete p;
  //cout << *p;异常
}

如果是new一个数组

//new一个数组
int* arr = new int[10];
//释放一个数组
delete[] arr;

注意

代码区和全局区是程序编译成exe可执行文件的时候就已经有了,但是栈区和堆区是程序exe文件执行后产生的

2.为什么划分内存(内存划分意义)

将不同的数据放在不同的区域,赋予不同的生命周期,提高编程灵活程度

3.引用

使用引用给一个变量起别名

#include <iostream>
using namespace std;
 
int main() {  
  int a = 10;
  /*1.定义引用的格式  数据类型 &别名=原名
  *2.引用必需要初始化
  *3.引用初始化后,不可更改
  */
  int& b = a;
  cout << b;//10
}

前面文章中的地址传递会修改实参,值传递不会修改实参,引用作为函数参数会修改实参,简化使用指针修改实参的复杂过程

#include <iostream>
using namespace std;
void swap(int &a,int &b) {
  int temp = a;
  a = b;
  b = temp;
}
int main() {  
  int a = 10;
  int b = 20;
  swap(a,b);
  cout << a;//20
  cout << b;//10
}

局部变量不能作为函数的返回值返回

#include <iostream>
using namespace std;
int& f() {
  int a = 10;//栈区中的局部变量在函数执行完后释放
  return a;
}
int main() {  
  int &a = f();
  cout << a;//10 编译器保留
  cout << a;//不在是10
}

如果是局部静态变量,可以返回

#include <iostream>
using namespace std;
int& f() {
  static int a = 10;//栈区中的局部变量在函数执行完后释放
  return a;
}
int main() {  
  int &a = f();
  cout << a;//10
  cout << a;//10
}
#include <iostream>
using namespace std;
int& f() {
  static int a = 10;//栈区中的局部变量在函数执行完后释放
  return a;
}
int main() {  
  int &a = f();
  cout << a;//10
  cout << a;//10
  f() = 100;//如果函数的返回是一个引用,可以作为左值
  cout << a;//100
  cout << a;//100
}

引用本质是指针常量

int main() {  
  int a = 1;
  //内部发现是引用,自动转成指针常量 int * const b=&a;
  int& b = a;
  b = 2;//内部发现是引用,自动转成*b=20;
  cout << a;//2
  cout << b;//2
}

常量引用

#include <iostream>
using namespace std;
//使用const修改函数形参,防止误操作
void f(const int& a) {
  //a = 100;不允许修改
}
int main() {  
  int& b = 1;//引用本身需要一个合法内存空间,所以这行代码有误
  int a = 10;
  f(a);
}

 

4.函数相关

前面c++基础系列有关函数知识有所描述,这里补充一些函数高级知识

1.c++中函数可以有默认值

#include <iostream>
using namespace std;
//1.c++中函数可以有默认值,并且某个位置有了默认值,那么从这个位置开始左到右都的有默认值
int f(int a, int b = 10,int c=20) {
  return a + b + c;
}
int main() {  
  int a = 10;
  //2.如果函数有默认值,当我们传值使用传递的值,不传值使用默认的
  cout<<f(a);//40
  cout << f(a, 20);//50
}
//3.声明和实现只能有一个有默认参数
int f1(int a, int b = 10);
int f1(int a, int b) {
  return a + b;
}

2.c++函数中可以有占位参数用来占位,调用函数必需填补该位置

#include <iostream>
using namespace std;
 
//1.只写一个数据类型就是占位
void f(int a,int) {
  cout << "test";
}
//2.占位参数可以有默认值
void f1(int a, int=10) {
  cout << "test";
}
int main() {  
  int a = 10;
  f(a, 10);//占位参必须填补
}

3.函数重载

定义:同一个作用域下,两个函数参数类型不同或者参数顺序不同或者个数不同。此时这两个函数名字可以相同。提高复用性

#include <iostream>
using namespace std;
 
void f(int a,int b) {
  cout << "test";
}
 
void f(int a) {
  cout << "test";
}
int main() {  
  int a = 10;
  f(a, 10);
}

注意:函数返回值不能作为函数重载的条件

4.引用也可作为函数重载条件

#include <iostream>
using namespace std;
 
void f(int &a) {//int &a=10;不合法
  cout << "test";
}
 
void f(const int &a) {//const int &a=10;合法
  cout << "test111";
}
int main() {  
  int a = 10;
  f(a);//test
  f(10);//test111
}

5.函数重载遇到默认参数需要注意

void f(int a,int b=10) {//int &a=10;不合法
  cout << "test";
}
 
void f(int a) {//const int &a=10;合法
  cout << "test111";
}
int main() {  
  int a = 10;
  f(a);//报错,出现二义性
}



相关文章
|
5月前
|
存储 弹性计算 缓存
阿里云服务器ECS经济型、通用算力、计算型、通用和内存型选购指南及使用场景分析
本文详细解析阿里云ECS服务器的经济型、通用算力型、计算型、通用型和内存型实例的区别及适用场景,涵盖性能特点、配置比例与实际应用,助你根据业务需求精准选型,提升资源利用率并降低成本。
441 3
|
1月前
|
设计模式 缓存 Java
【JUC】(4)从JMM内存模型的角度来分析CAS并发性问题
本篇文章将从JMM内存模型的角度来分析CAS并发性问题; 内容包含:介绍JMM、CAS、balking犹豫模式、二次检查锁、指令重排问题
102 1
|
4月前
|
存储 人工智能 自然语言处理
AI代理内存消耗过大?9种优化策略对比分析
在AI代理系统中,多代理协作虽能提升整体准确性,但真正决定性能的关键因素之一是**内存管理**。随着对话深度和长度的增加,内存消耗呈指数级增长,主要源于历史上下文、工具调用记录、数据库查询结果等组件的持续积累。本文深入探讨了从基础到高级的九种内存优化技术,涵盖顺序存储、滑动窗口、摘要型内存、基于检索的系统、内存增强变换器、分层优化、图形化记忆网络、压缩整合策略以及类操作系统内存管理。通过统一框架下的代码实现与性能评估,分析了每种技术的适用场景与局限性,为构建高效、可扩展的AI代理系统提供了系统性的优化路径和技术参考。
246 4
AI代理内存消耗过大?9种优化策略对比分析
|
4月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
186 26
|
5月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
103 1
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
156 0
|
8月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
8月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
468 6
|
4月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
1527 0
|
4月前
|
存储 缓存 NoSQL
内存管理基础:数据结构的存储方式
数据结构在内存中的存储方式主要包括连续存储、链式存储、索引存储和散列存储。连续存储如数组,数据元素按顺序连续存放,访问速度快但扩展性差;链式存储如链表,通过指针连接分散的节点,便于插入删除但访问效率低;索引存储通过索引表提高查找效率,常用于数据库系统;散列存储如哈希表,通过哈希函数实现快速存取,但需处理冲突。不同场景下应根据访问模式、数据规模和操作频率选择合适的存储结构,甚至结合多种方式以达到最优性能。掌握这些存储机制是构建高效程序和理解高级数据结构的基础。
457 1