对象的动态建立和释放,赋值和复制

el/2024/4/13 14:30:23

一、对象的动态建立和释放

利用new运算符可以动态地分配对象空间,delete运算符释放对象空间

动态分配对象的一般形式:

new 类名;

new运算符动态分配得到的对象是无名的,它返回一个指向新对象的指针的值,即所分配的内存单元的起始地址。程序通过这个地址可以间接访问这个对象,因此需要定义一个指向类的对象的指针变量来存放该地址。

类名 * 对象指针变量;

对象指针变量= new类名;
如: student *p;    p = new student;
在执行new运算时,如果内存不足,无法开辟所需的内存空间,C++编译器会返回一个0值指针(NULL)。因此,只要检测返回值是否为0,就可以判断动态分配对象是否成功,只有指针有效时才能使用对象指针。

当不再需要使用由new建立的动态对象时,必须用delete运算予以撤销
如: delete p;
注意:new建立的动态对象不会自动被撤销,即使程序运行结束也是如此,必须人为使用delete撤销。

#include<iostream>
using namespace std;
class Object
{
private:int value;
public:Object(int x = 0) :value(x) {}void Print()const { cout << value << endl; }
};
void fun()
{Object obja(20);//.stack
}
int main()
{Object objb(40);fun();Object* p = new Object(30);//new 1.申请空间 2.创建对象 3.返回创建好对象的地址  .heapp->Print();delete p;//不需要时delete
}

 Object *p = new Object[n];//一次构建多个对象时,必须有缺省构造函数,没有缺省构造函数,无法连续构建对象。(如果构造函数没有参数,或者构造函数的所有参数都有默认值,就可以称其为缺省构造函数。一个类中,只能有一个缺省构造函数。)

 

 

二、对象的赋值和复制

1>对象的赋值

如果一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值。

对象赋值的一般形式:

对象名1=对象名2;

关于对象赋值的说明:
1)对象的赋值只对其中的非静态数据成员赋值,而不对成员函数赋值。
2)对象的数据成员中不能包括动态分配资源的数据,否则在赋值时可能出现严重后果。

2>对象的复制

有时需要用到多个完全相同的对象,就可以用一个已有对象快速地复制出多个完全相同的对象。

对象复制的一般形式:

类名  对象名2 (对象名1);

 student stu2 (stu1) ;

在建立对象时调用一个特殊的构造函数—复制构造函数。如果用户未定义复制构造函数,则编译系统会自动提供一个默认的复制构造函数。

如: student stu2 (stu1) ;

对应的复制构造函数:

student::student(const student &stu)
{ num=stu.num;name=stu.name;score =stu.score;
}
#include<stdio.h>
#include<iostream>
using namespace std;class student
{
private:int num;string name;float score;
public:student(int n, string m, float s) :num(n), name(m), score(s){};student(const student& stu);void display(){cout << "num:" << num << endl;cout << "name:" << name << endl;cout << "score:" << score << endl;}
};
student::student(const student&stu)//复制构造函数
{num = stu.num;name = stu.name;score = stu.score;
}
int main()
{student stu1(2020, "zhangsan", 85);student stu2(stu1);//复制stu1.display();stu2.display();return 0;
}

C++还提供了另一种方便用户使用的复制形式——用赋值号代替括号
对象复制的一般形式:
类名  对象名2 = 对象名1;

对象的赋值和对象的复制区别:
1)对象的赋值是对一个已经存在的对象赋值,必须先定义被赋值的对象,才能进行赋值。
2)如果对象的复制是建立个新对象,并使它与一个已有对象完全相同。

普通构造函数和复制构造函数的区别:

1)声明形式上不同。

类名 (形参列表)

类名 (类名 &对象名)
如: student( int num, string name, int score);
      student (student &stu);
2)建立对象时,实参类型不同。
如: student stu1( 20060102,“张三”,86 );
      student stu2( stu1);

3)普通构造函数在建立对象时被调用。

复制构造函数在用已有对象复制新对象时被调用。


http://www.ngui.cc/el/4994639.html

相关文章

文件查看命令和用户管理命令

文件查看命令 cat 1.用于查看文件数据 cat a.txt 2.合并文件 cat a.txt b.txt > c.txt 3.向文件中写入数据 cat > d.txt 这样写入数据有一点需要注意&#xff1a;cat > d.txt 输入数据时&#xff0c;会先将d.txt中的数据清空。 cat >> d.txt 向文件的末…

左值右值,柔性数组

一、右值、左值 在c中&#xff0c;左值就是可以被赋值的&#xff0c;右值就是不可被赋值的 在c11标准下: 所有的值必属于左值、右值两者之一。 右值分为纯右值和将亡值 在C11中可以取地址的、有名字的就是左值&#xff0c;反之&#xff0c;不能取地址的、没有名字的就是右值&a…

C++统一初始化和输入输出

一、c统一初始化 C语言中初始化一个量只有赋值语句这一种办法 c中初始化方式比较多 #include<iostream> using namespace std;int main() {int a 10;//c语言中初始化只有赋值语句这一种方法//以下都是c初始化的方法int b(10);//这样有点像对象初始化的形式int c{ 10 …

如何判断是以c++方式编译还是c方式编译

如何判断是以c方式编译还是c方式编译&#xff1f; 通过宏判断&#xff0c;c方式编译有宏 _cplusplus c中没有_cplusplus 在程序中可以利用开关语句&#xff08;探测宏&#xff09; #ifdef _cplusplusprintf("c"); #elseprintf("c"); #endif

关于log4j和slf4j的使用说明

1.log4j是日志类基础&#xff0c;slf4j需要依赖他&#xff0c;同时还需要一个log4j和slf4j的媒介来整合他们俩。简而言之&#xff0c;log4jslf4j&#xff08;slf4j--log4j&#xff09;三位一体才能爽歪歪&#xff01; 2.三者的版本如何搭配选择&#xff1f;答案是&#xff0c;…

通过jug 2.0.jar的成功下载的猜想

1.maven的配置为以下方式时&#xff0c;下载出错 <dependency> <groupId>org.safehaus.jug</groupId> <artifactId>jug</artifactId> <version>2.0.0</version> </dependency> 2.maven以以下配置时&#…

关于项目突然启动缓慢或者停留在Initializing Spring FrameworkServlet xx的原因

1.原因很简单&#xff0c;因为你的项目里出现了断点&#xff0c;所以加载项目很慢&#xff0c;如果你给tomcat设置启动时间了&#xff0c;那么通tomcat就启动失败&#xff01; 2.至于你为什么仔细检查了项目&#xff0c;都没有发现断点&#xff0c;原因很简单&#xff0c;你是…

hql出现could not initialize proxy - no Session的另外一个原因

1.重中之重的原因是表中有非空字段&#xff0c;但是你save or update之时没有注意这个&#xff0c;然后才报了这个错误&#xff01; 2.当然还有就是延迟加载设置的策略&#xff0c;这个你可以搜索别的文章看一看如何设置

微信爬虫机器人的坑篇之无法获取群组的解决方案

1.微信爬虫实现的方案&#xff0c;详情请参考此链接&#xff0c;作者已经说得很明白了https://blog.csdn.net/wonxxx/article/details/51787041 2.但是如果你根据作者这些分析进行机器人操作的话&#xff0c;其中 获取好友列表&#xff08;webwxgetcontact&#xff09;这个功能…

使用SocketChannel和ServerSocketChannel之Address already in use: bind

出现该问题的原因&#xff0c;一个是因为服务器多开了&#xff0c;另外一个极其隐蔽的原因就是客户端使用了bind&#xff08;地址&#xff0c;端口&#xff09;,而服务端也使用了bind&#xff0c;因此导致端口冲突