C++_概念的进一步理解-声明和定义-初始化和赋值

变量的概念

    数据类型
	  字面值常量: 直接在代码中表示的值,它们不需要声明即可使用
    1.定义提供一个具名的、可供程序操作的存储空间(内存中),用以临时存储输入数据、中间结果和最终结果。 
	     属性变量有三个重要属性:名称、值、类型	
	    C++区分了声明和定义	 
	    	变量的声明:用于向程序表明变量的类型和名字 
	    	变量的定义  用于为变量分配存储空间,还可以为变量指定初始值
	    	
	    C++内存模型:--编译器和操作系统  用户态的内存地址
	        全局/静态存储区(Global/Static Storage)   
            栈(Stack) 栈内存用于存储局部变量和函数调用信息		
	        堆(Heap)  堆内存用于存储动态分配的对象
	    	常量存储区(Constant Storage   
    2.从数据的角度--变量指的是在程序运行中,可以发生变化的量;是存放数据值的容器
	    常量
        变量名 计算机语言中能储存计算结果或能表示值的抽象概念			

定义和声明

定义和初始化  赋值
  初始化--赋值初始化, 函数返回值初始化	
  在类外定义非内联成员函数。
声明
   
    extern int b;  //声明,不是定义
	extern int b = 20;  //是定义  显示初始化的声明即定义
    int a = 10;    //定义就是声明
    变量声明  函数声明 类声明
     定义 不仅声明了名字,还实际分配了内存空间(对于变量)
	                    或提供了具体的实现(对于函数、类等) 函数原型是一个声明,而函数的实现则是定义		
	声明仅仅是将一个符号引入到一个作用域。而定义提供了一个实体在程序中的唯一描述 
    将具有外部链接的定义放在头文件中几乎都是编程错误。因为如果该头文件中被多个源文件包含,那么就会存在多个定义,链接时就会出错。
###分离式编译机制
   文件间共享代码的方式-- 将声明和定义区分开来	

初始化和赋值

初始化 Initialization
	是指在变量或对象被创建时,给它赋予一个初始的值。初始化是分配内存并为变量或对象提供初始值的过程,通常是在声明变量或创建对象时发生的
      变量初始化:  基本类型变量初始化  指针初始化
	  对象初始化:  调用类的构造函数来初始化对象的成员变量 
	初始化通常在变量或对象声明时发生,赋值是对象或变量已经存在时对其进行更新。
	初始化是内存分配和赋初值的过程,变量或对象首次被创建时进行 
    
	初始化  int a = 10; // 直接初始化
	        std::vector<int> vec{1, 2, 3, 4}; // 列表初始化  列表初始化(List Initialization): 直接列表初始化与拷贝列表初始化
			std::vector<int> vec = {1, 2, 3}; //这实际上是先创建一个临时对象,然后通过拷贝构造函数或移动构造函数来构造目标对象
			构造函数初始化  
赋值(Assignment)
    赋值是指在变量或对象已经被初始化(或声明)后,将一个新的值赋给它。赋值操作通常会覆盖变量之前存储的值
       变量赋值
       对象赋值  // 赋值运算符重载
	赋值是在变量已经被初始化或对象已经创建后,对其值进行改变,赋值不会重新分配内存,而只是将新的值赋给现有的变量或对象   

   语法很相似:
        初始化通常在声明时进行,使用 = 操作符将初始值给变量或对象。
        赋值是在变量声明和初始化之后使用 = 操作符改变其值。	 
元素添加
    使用成员函数(如push_back)来添加元素

作用域

   scope作用域和命名空间
      命名空间域是指用 namespace 声明的作用域
      类域是类中定义的成员变量或成员函数的作用范围
	  局部域 指的是在函数或代码块(如 if、for、while 等)内部定义的变量的作用范围
	  全局域 指的是定义在所有函数或类之外的变量。全局变量可以在整个程序中访问,任何函数或类都能使用它(除非被 static 修饰)。
	  :: 是作用域解析运算符,用于区分不同域中的同名变量

    头文件+库文件

    头文件+源文件
        头文件:包含结构声明和使用这些结构的函数的原型
        源代码文件:包含与结构有关的函数的代码
        源代码文件:包含调用与结构相关的函数的代码		
		
	嵌套 nested		
	
	const      该变量修饰为常量,从而不可以修改  
	constexpr  用来修饰一些函数和变量,使其成为常量表达式
	static
	static 主要控制变量的存储位置和可见性,而const则控制变量的可变性  静态
	     static类成员变量属于类本身   静态全局变量  静态成员变量  静态成员函数

指针

指针 --是一个对象
引用
   左值引用--引用不是一个对象
     引用是:通过更改一个变量的引用就能达到更改该变量的效果。指针是:通过访问一个变量的地址,对其解引用后也可以更改该变量的值
	 对指针的引用  对常量的引用
	 
	 采用传递引用的方式,因为引用只是变量的一个别名,不占用内存,所以不会发生拷贝行为。
	    但是引用传递有一个问题,那就是形参可以改变实参的值。
	   所以为了避免意外修改导致实参的值发生改,通常会采用const加上引用的方式传递参数
	 
   右值引用
   
  

   在C++中,引用的符号为”&“,和取地址的符号是一样的。引用的前提是必须得有一个变量作为引用的对象	 
   int a = 10;
   int& c = a;//引用a,并且别名叫c(注意别名类型与本名类型保证一致)
  
别名可以通过`typedef`或`using`关键字来定义

左值引用和右值引用

左值引用和右值引用
    传统的C++引用,即是左值引用
         在C++中,左值引用的符号为”&“ 
         左值有名字,能够被多个地方引用,生命周期较长			 
    右值引用:
        右值引用使用 && 符号来声明,表示对右值的引用
		右值不具名,只能通过引用的方式找到  捕获右值的临时对象:右值引用可以绑定到右值,如临时对象或字面量,使我们能够操作这些临时值。
移动语义的实现通常涉及移动构造函数和移动赋值运算符。		
    移动构造函数: 临时对象(右值)。用到临时对象的时候就会执行移动语义	
        移动函数	   MyClass(MyClass&& other) {} // 移动构造函 两个&操作符, 移动构造函数接收的是“右值引用”的参数。
    	一个右值引用(rvalue reference)创建新的对象,而无需进行深拷贝(deep copy)
    移动赋值运算符 Foo& operator=(Foo&& foo)
     		同复制赋值运算符,唯一不同是参数为右值
    
	
右值引用的核心用途主要包括移动语义和完美转发。		
   std::move(),它可以将一个左值强制转换为右值引用  
   std::forward 是C++11引入的函数模板,它的作用是实现函数参数的完美转发,通俗的讲就是根据传入的参数,决定将参数以左值引用还是右值引用的方式进行转发

   简单之处在于理解动机:C++为什么需要完美转发?
       完美转发可以确保 arg 被正确转发为左值或右值,以避免额外的拷贝或不必要的移动
	   让模板函数能够适应各种不同的参数类型(左值、右值、const 引用等),并保持参数的原始特性 
   复杂之处在于理解原理:完美转发基于万能引用,引用折叠以及std::forward模板函数
       左值右值在函数调用时,都转化成了左值,使得函数转调用时无法判断左值和右值。
       允许程序员更加细粒度的处理对象拷贝时的内存分配问题,提高了对临时对象和不需要的对象的利用率


C++程序中,不必要的对象复制会导致额外的CPU和内存开销。使用移动语义和引用(尤其是右值引用)可以避免这种开销
posted @ 2025-04-14 18:02  辰令  阅读(50)  评论(0)    收藏  举报