2000年至今,由于以Loki、MPL(Boost)等程序库为代表的产生式编程和模板元编程的出现,C++出现了发展历史上又一个新的高峰,这些新技术的出现以及和原有技术的融合,使C++已经成为当今主流程序设计语言中最复杂的一员-维基百科C++词条

丰富的程序库以及本身的语言特性,使得C++在开发效率和运行效率上有着不错平衡,但这同时也增加了学习C++所带来的时间成本,C++疑问集此系列用于记录笔者学习C++路上遇到的问题,对部分易于混淆的知识点加以总结与汇总,以便于读者对C++有更深入的了解。

创建对象的两方法

1
A a1 = A;		//在栈上创建一个A类的对象a1

创建对象时在栈上分配用于保存其数据成员的内存空间,其成员函数保存在公共代码区
栈的内存分配由操作系统决定,所以函数执行完毕,操作系统会自动释放内存。

  • 优点:系统自动分配和回收内存,数据存取块
  • 缺点:栈的最大容量由系统预先设定好的,能获得的空间较小
1
2
A a2 = new A();	//在堆上创建一个A类的对象a2
delete a2; //释放对象a2的内存空间sd

创建对象时在堆上分配用于保存其数据成员的内存空间,其成员函数保存在公共代码区
堆的内存分配由使用者决定,所以函数执行完毕,需要使用者手动delete对象

  • 优点:堆的大小受限与有效的虚拟内存,能获得的空间大
  • 缺点:由new分配的内存,系统响应速度较慢,容易产生内存碎片,忘记释放内存,容易导致内存泄漏

c++编译器内存分布

全局数据区:分初始化区和未初始化区,存放全局变量(extern),静态数据(static)
常量区:存放常量(注意:const局部变量存储在栈区)
代码区:函数代码的公共存放区域
栈区:非new方法构造对象,存放对象的数据成员(注意:int main(){…}属于非new构造对象,其数据成员也存放在栈区)
堆区:new方法构造对象,存放对象的数据成员
Tips:c++每个对象所占用的存储空间只是该对象的数据成员(虚函数指针和虚基类指针也属于数据部分)所占用的存储空间,而函数代码则存放在公共函数代码的存储空间,两者的存储空间互不影响。
c++编译器内存分布

创建指针对象/创建引用的区别

1
2
3
int a = 1;
int *p = &a; //创建指针对象
int &r = a; //创建引用
创建指针对象 创建引用
内存空间 编译器为指针分配内存 编译器器不为引用分配内存,sizeof方法显示为所引用对象的内存
初始化 定义时可以不初始化 必须初始化
可否为空 指针可以为空 引用不可为空
指向性 指针可以指向其他对象 引用一旦创建不可以更改其指向

指针常量与常量指针

const int i = 1; const int *p1 = &i; int const *p2 = &i; int *const p3 = &i;
整形常量(const int) 指向常量的指针/*指针常量(pointer to const) 指向常量的指针/*指针常量(pointer to const) *常量指针(const pointer)
常量为只读状态,其值不可改变 指针指向的内容为常量,常量不可改变 指针指向的内容为常量,常量不可改变 指针自身为常量,始终指向同一个地址(定义时必须初始化)
const int i = 1;
i = 2;
//Error,i为只读状态,其值不可改变
(error: assignment of read-only variable ‘i’)
int i =1;
int j =2;
const int *p1 = &i;
i = 100;//OK
p1 = &j;//OK
*p1 = 100;
//Error,*p1为常量,其值不可变
(error: assignment of read-only location ‘* p1’)
注意:*p1的值不可变指的不可通过*p1=100这种方式改变,可通过类似上方i = 100的方式改变其所指的值。
int i =1;
int j =2;
int const *p2 = &i;
i = 100;//OK
p2 = &j;//OK
*p2 = 100;
//Error,*p2为常量,其值不可变(error: assignment of read-only location ‘*p2’)
注意:*p2的值不可变指的不可通过*p2=100这种方式改变,可通过类似上方i = 100的方式改变其所指的值。
int i =1;
int j =2;
int *const p3 = &i;
i = 100;//OK
p3 = &j;
//Error,指针p3为常量,指针p3的地址不可变(error: assignment of read-only variable ‘p3’)
*p3 = 100;//OK

注意:指针常量(pointer to const)和常量指针(const pointer),这两个名词的中文翻译是经常引起争议的地方,而造成争议的地方就在于(const pointer)的中文翻译,详情见下表:

指针常量(pointer to const)和常量指针(const pointer) 常量指针(pointer to const)和指针常量(const pointer)
《c++ primer(第五版)中文版》2.4.2指针和const一节中,作者将(pointer to const)翻译为指向常量的指针,将(const pointer)翻译为常量指针,这是目前大家比较认同的翻译。而《c++ primer plus(第六版)中文版》为了避免歧义,作者将(pointer to const)翻译为指向const的指针,将(const pointer)翻译为const指针。 这种翻译方式来源于我们对常量的普遍翻译,例如(const int)一般我们将其称为整形常量,所以自然而然一部分程序员就会将(const pointer)翻译为指针常量。

才学疏浅,欢迎评论指导

评论