C++创建对象的三种方式
C++在创建对象的时候,有三种方式:
#include <iostream>
using namespace std; class A
{
private:
int n;
public:
A(int m):n(m)
{ }
~A(){}
};
int main()
{
A a(1); //栈中分配
A b = A(1); //栈中分配 A* c = new A(1); //堆中分配
delete c;
return 0;
}
第一种和第二种没什么区别,一个隐式调用,一个显式调用,两者都是在进程虚拟地址空间中的栈中分配内存,而第三种使用了new,在堆中分配了内存,而栈中内存的分配和释放是由系统管理,而堆中内存的分配和释放必须由程序员手动释放。采用第三种方式时,必须注意一下几点问题:
- new创建类对象需要指针接收,一处初始化,多处使用
- new创建类对象使用完需delete销毁
- new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间
- new对象指针用途广泛,比如作为函数返回值、函数参数等
- 频繁调用场合并不适合new,就像new申请和释放内存一样
- 栈的大小远小于堆的大
- 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
提示:
对于栈的效率比堆要高的多这件事,你可以通过在代码中设置断点来看构造函数的执行过程,在堆中分配内存要经过好多的库函数的执行。
C++并不像Java和C#这样的纯粹的面向对象的编程语言:类类型是引用类型,必须在堆内存中开辟对象空间,结构体是值类型。
在C++中,类和结构体其实没啥区别,结构体也可以封装、继承。类在不使用new申请创建对象的时候,也会在栈中为对象分配内存,并且不需要一个指针变量指向对象。所以类在本质上和结构体没有区别。要说区别,那唯一的区别就是:成员变量的默认访问权限:结构体是public的,类是private的。
同时,类的结构体一样,数据成员要在内存中保持对齐的方式。
new出来的所有的东西都放在堆上,new class、new struct甚至new一个int都会放到堆上,并且要在栈中有一个对应的指针变量指向堆中的这个对象。
class A
{
private:
int n;
int w;
int t;
double d;
public:
A(int _n, int _w, int _t, double _d )
{ }
~A(){}
}; int main()
{
A a(1,2,3,3.5); //栈中分配
A b = A(1,2,3,3.5); //栈中分配
A* c = new A(1,2,3,3.5); //堆中分配 cout << sizeof(int) << endl; //结果是4
cout << sizeof(double) << endl; //结果是8
cout << sizeof(a) << endl; //结果是24
cout << sizeof(c) << endl; //结果是4
cout << sizeof(*c) << endl; //结果是24 delete c;
return 0;
}
C++创建对象的三种方式的更多相关文章
- spring入门:beans.xml不提示、别名、创建对象的三种方式
spring的版本是2.5 一.beans.xml文件不提示 Location:spring-framework-2.5.6.SEC01\dist\resources\spring-beans-2.5 ...
- Spring笔记03(Spring创建对象的三种方式)
1.创建对象的三种方式和bean的生命周期的验证: Animal接口代码: package cn.pb.dao; /** * 动物接口 */ public interface Animal { //吃 ...
- Spring创建对象的三种方式以及创建时间
创建对象的三种方式: 1.采用默认的构造函数创建 2.采用静态工厂方法 1.写一个静态工厂方法类 public class HelloWorldFactory { public static Hell ...
- js创建对象的三种方式
<script> //创建对象的三种方式 // 1.利用对象字面量(传说中的大括号)创建对象 var obj1 = { uname: 'ash', age: 18, sex: " ...
- js创建对象的三种方式和js工厂模式创建对象
文章地址: https://www.cnblogs.com/sandraryan/ 创建对象 创建对象的三种方式 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象 1. 调用系统的构造函数 ...
- JavaScript中创建对象的三种方式!
JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...
- [UE4]C++创建对象的三种方式
#include <iostream> using namespace std; class A { private: int n; public: A(int m):n(m) { } ~ ...
- js中创建对象的三种方式
1. 对象字面量 var obj={ name:"小小", age:3, car:{ brand:"baoma", } }; } 2.使用内置构造函数 var ...
- 4 spring 创建对象的三种方式
方式1. 通过构造方法创建 1.1 无参构造创建:默认情况. 1.2 有参构造创建:需要明确配置 1.2.1 需要在类中提供有参构造方法 1.2.2 在 ...
随机推荐
- SQL Server 排名函数实现
在SQL Server 中有四大排名函数分别是: 1.row_number() 2.ntile() 3.rank() 4.dense_rank() -------------------------- ...
- JAVA并发,线程工厂及自定义线程池
package com.xt.thinks21_2; import java.util.concurrent.ExecutorService; import java.util.concurrent. ...
- 浅谈qt 布局器
在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...
- mysql 批量删除分区
alter table titles drop partition p01; use zabbix; mysql> source drop_par.sql [oracle@oadb mysql] ...
- openStack deep dive,Retake Policy
Method of Payment: visa MasterCard American Express Discover
- mongoose查询特定时间段文档的方法
db.collection.find({ time:{ "$gte": new Date('2014-01-24'), "$lte":new Date('201 ...
- Android 动画animation 深入分析
转载请注明出处:http://blog.csdn.net/farmer_cc/article/details/18259117 Android 动画animation 深入分析 前言:本文试图通过分析 ...
- word排版论文小结
毕业论文如何用WORD排版 本人折腾了一晚上看别人的百度经验,做个总结,方便后人看懂,其实特别简单 用WORD自动生成页码 第一种情况:从第一页或者从第二页开始设置页码 这种情况只要“插入-> ...
- JS图表组件 highcharts 简单的介绍
把highcharts拿来做个简单的介绍,希望更多的朋友可以用到这个用来做图表的js插件. preparation Highcharts Highcharts是一个制作图表的纯Javascript类库 ...
- CDOJ 1259 昊昊爱运动 II bitset+线段树
题目链接 昊昊喜欢运动 他N天内会参加M种运动(每种运动用一个[1,m]的整数表示) 现在有Q个操作,操作描述如下 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) 问昊昊第l天到第r天参加了 ...