对象的动态创建和销毁以及对象的复制,赋值

简介: 🐰对象的动态创建和销毁🐰对象的复制🐰对象的赋值

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰对象的动态创建和销毁

🐰对象的复制

🐰对象的赋值


🐰对象的动态创建和销毁

new和delete这两个运算符实现对内存的动态申请与释放的。如果要动态创建和销毁对象也使用这两个运算符

例如有一个类为Box,可以动态创建一个对象:

new Box;

这样系统就会从内存堆分配中一块内存空间,存放Box的对象,调用构造函数初始化对象。如果分配成功,new运算符会返回分配的内存的首地址;如果返回失败,则会返回一个NULL。但是通过new创建的对象没有名字,所以在使用new创建对象时都要声明一个指针变量保存对象的首地址,例如:

Box * ptr=new Box;

另外,还可以使用new创建对象时给出实参,调用有参的构造函数初始化对象

Box* ptr=new Box(2,2,2);

ptr指针就可以访问公用的成员了

ptr->volume();

如果动态创建对象失败,则会返回空指针,所以为了安全起见,可以判断指针是否为空

1. if(ptr!=NULL)
2. 
3. ptr->volume();

不需要使用动态创建的对象时,可以使用delete运算符销毁该对象

1. delete 指针名
2. 
3. delete ptr

这样就可以销毁ptr所指向的对象,将对象占用的空间归还给堆,使用new动态创建的对象只能通过delete进行销毁,系统不会进行自动销毁。如果不销毁,堆内存将被逐渐消耗。指针一旦指向动态创建的对象,就不要改变指针变量的值了,可能会造成动态创建创建的对象无法被销毁,也可能指针指向其他对象,delete销毁对象时可能会删错对象

🐰对象的复制

对象的复制是指在创建对象时使用已有对象快速复制出完全相同的对象

1. 类名 对象2(对象1);    代入法
2. 类名 对象2=对象1;    赋值法

其中对象1是和对象同类的并且已经存在的对象,在这种情况下,系统会调用一个称为“复制构造函数”的特殊的构造函数。复制构造函数会将对象1的各数据成员的值逐个复制到对象2中相应的数据成员。复制构造函数只有一个形参,这个形参就是本类的常引用。复制构造函数的函数体主要是将形参中对象的各数据成员值赋给自己的数据成员,为保证数据安全,引用加上const,看看复制构造函数的函数形式:

1. Box::Box(const Box &c)
2. {
3.     length=c.length; width=c.width; height=c.height;
4. }

即使程序中没有定义复制构造函数(每一个类都有一个复制构造函数),编译器会隐式地提供一个。即使定义了其他的构造函数,编译器也会提供一个复制构造函数,他会将实参对象的非static数据成员逐个复制到创建的对象中。

普通的构造函数和复制构造函数有哪些区别呢

(1)在形式上普通构造函数一般是形参列表,创建对象时通过实参列表给出初始化对象所需要各个数据成员的值。而复制构造函数的形参则只有一个,及本类对象的引用。

(2)在调用时系统会根据实际参数列表的类型来自动选择调用

(3)调用情况不一样,普通构造函数是创建对象时由系统自动调用;而复制构造函数是在使用已有的对象复制一个新对象时系统自动调用。以下三种情况才会复制对象:(1)创建一个新对象,并用同类对象初始化它。(2)函数参数是类对象(3)函数返回值是类对象

如果数据成员有指针变量时,复制构造函数会出现指针悬挂问题。

1. #include<iostream>
2. using namespace std;
3. class person
4. {
5. public:
6.     person(char* Name,int Age);
7.     person(const person &temp);
8.     ~person();
9.     void setAge(int x)
10.     {
11.         age=x;
12.     }
13.     void print();
14. private:
15.     char* name;
16.     int age;
17. };
18. person:: person(const person &temp)//复制构造函数
19. {
20.     name=new char[strlen(temp.name)+1];
21.     strcpy(name,temp.name);
22.     age=temp.age;
23.     cout<<"persson is called!!!"<<endl;
24. }
25. person::person(char* Name,int Age)//构造函数
26. {
27.     name=new char[strlen(Name)+1];
28.     strcpy(name,Name);
29.     age=Age;
30.     cout<<"persson is called!!!"<<endl;
31. }
32. person::~person()
33. {
34.     cout<<"persson is called"<<endl;
35.     delete []name;
36.     name=NULL;
37. }
38. void person::print()
39. {
40.     cout<<"name:  "<<name<<"age:  "<<age<<endl;
41. }
42. int main()
43. {
44.     person s1("张三",23);
45.     person s2(s1);
46.     s1.setAge(1);
47.     s2.setAge(2);
48.     s1.print();
49.     s2.print();
50.     return 0;
51. }

因此需要我们自己定义一个复制构造函数

🐰对象的赋值

对象赋值的一般形式:

对象1=对象2;

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  



相关文章
|
6月前
|
编译器 数据安全/隐私保护 C++
【类与对象】封装&对象的初始化及清理
【类与对象】封装&对象的初始化及清理
|
6月前
|
安全 编译器 C++
C++类与对象【对象的初始化和清理】
C++类与对象【对象的初始化和清理】
C++类与对象【对象的初始化和清理】
|
6月前
|
存储 编译器 C++
36对象的赋值和复制
36对象的赋值和复制
32 0
对象的相等和引用相等的区别
对象的相等和引用相等的区别
|
Java 编译器 C++
C++冷知识:构造函数初始化时,为什么使用 : 而不是使用作用域内初始化对象?
在这个例子中,初始化列表中的成员变量顺序与类定义中的顺序不一致,可能会导致未定义的行为。 如果成员变量是const或引用类型,必须在初始化列表中进行初始化,否则会导致编译错误。
68 0
|
Java 编译器
对象的构造及初始化
对象的构造及初始化
87 0
|
Java 编译器
创建一个对象的时候
创建一个对象的时候
76 0
引用调用
引用调用
112 0
|
数据库 C++
确定对象使用前已先被初始化
确定对象使用前已先被初始化
170 0
|
存储 C++ 块存储
C++对象的复制——具有指针成员的类的对象的复制
//smartvessel@gmail.com class Table{Name * p;size_t sz;publish:Table(size_t s = 15){p = new Name[sz=s];}~Table(){delete[]p ;}.
954 0