[关闭]
@cxm-2016 2016-10-28T13:13:51.000000Z 字数 2958 阅读 1713

C++:对象数组与this指针

c++

版本:2
作者:陈小默
声明:禁止商用,禁止转载

该文章仅被发布于作业部落(原)CSDN


声明对象数组

由于在C++中我们可以直接操作堆和栈,所以在声明时我们也需要选择数组的创建方式。有一种最显而易见的方法去判断变量的存储状态,就是看对象创建时有没有用new关键字。
1,栈数组栈对象
顾名思义就是数组和对象都在当前栈中分配,带来的好处就是对象数组的生命周期有限,我们不需要去手动释放栈中的内存,但是缺点就是创建的对象我们只能在当前栈帧中使用,不能直接将引用返回到其他栈帧。

  1. Student stu[3]={
  2. Student("Jack",90,97,89),
  3. Student("Sue",92,95,100),
  4. Student("Sam",89,98,99)
  5. };

当stu的生命周期终结时,其中所有对象的析构函数都将会被调用。

2,栈数组和堆对象
有时我们需要将分散在堆中数据进行汇总操作,这时就可以使用这种方式创建一个指针数组

  1. Student *students[3]={
  2. new Student("Jack",90,97,89),
  3. new Student("Sue",92,95,100),
  4. new Student("Sam",89,98,99)
  5. };

当students生命周期结束时,这个数组将会被销毁并清空其中的引用。但其中的Student对象仍在堆中存在,并且此时没有任何指针指向这些内存,长此以往将会导致内存泄漏。

this指针

在C++中,this是一个指针常量,指向当前正在调用这个方法的对象。

  1. stu[1].show();

如果在show方法中使用了this指针,则这个this指针就代指stu[1]对象。

代码示例

我们以一个学生列表查找最好成绩的例子来演示本节内容,首先仍然是创建一个头文件student.h

  1. //student.h -- Student class interface
  2. //version 00
  3. #ifndef STUDENT_H_
  4. #define STUDENT_H_
  5. #include <string>
  6. class Student{ //class declaration
  7. private:
  8. std::string name;
  9. int ch;
  10. int en;
  11. int math;
  12. float average;
  13. void count(){
  14. average = (ch + en + math+0.0F)/3;
  15. }
  16. public:
  17. Student();
  18. Student(std::string name,int chScore,int enScore,int mathScore);
  19. ~Student();
  20. Student & max1(Student & stu);
  21. Student * max2(Student * stu);
  22. void show();
  23. };
  24. #endif

然后我们去实现student.cpp,注意,这里我们提供了为上述两种数组的创建方式提供了比较的办法,在max中,我们向一个对象传递了另一个对象的引用,当我们进行判断之后选择是返回自身对象的引用(this)或者是参数对象的引用。

  1. //student.cpp -- implementing the Student class
  2. //version 00
  3. #include "stdafx.h"
  4. #include "student.h"
  5. Student::Student(){}
  6. Student::Student(std::string n,int chScore,int enScore,int mathScore):name(n),ch(chScore),en(enScore),math(mathScore){
  7. count();
  8. }
  9. Student::~Student(){
  10. cout<<"再见! "<<name<<"."<<endl;
  11. }
  12. Student & Student::max1(Student & stu){
  13. float a1= (*this).average;
  14. float a2=stu.average;
  15. return a1>a2?*this:stu;
  16. }
  17. Student* Student::max2(Student * stu){
  18. float a1= this->average;
  19. float a2= stu->average;
  20. return a1>a2?this:stu;
  21. }
  22. void Student::show(){
  23. Student::count();
  24. ios_base::fmtflags orig = cout.setf(ios_base::fixed,ios_base::floatfield);
  25. std::streamsize prec = cout.precision(1);
  26. cout<<name<<" 同学的语文成绩为"<<ch<<"分,数学成绩为"<<math<<"分,英语成绩为"<<en<<"分,平均成绩"<<average<<"分"<<endl;
  27. cout.setf(orig,ios_base::floatfield);
  28. }

我们在main方法中实现代码

  1. //Visual Studio 2010 -- main program
  2. #include "stdafx.h"
  3. #include "student.h"
  4. void fun1();
  5. void fun2();
  6. int _tmain(int argc, _TCHAR* argv[]){
  7. fun1();
  8. cout<<endl;
  9. fun2();
  10. return 0;
  11. }
  12. void fun1(){
  13. Student students[3]={
  14. Student("Jack",90,97,89),
  15. Student("Sue",92,95,100),
  16. Student("Sam",89,98,99)
  17. };
  18. Student max = students[0];
  19. for(int i=1;i<3;i++){
  20. max = max.max1(students[i]);
  21. }
  22. max.show();
  23. }
  24. void fun2(){
  25. Student *students[3]={
  26. new Student("Jack",90,97,89),
  27. new Student("Sue",92,95,100),
  28. new Student("Sam",89,98,99)
  29. };
  30. Student * max = * students;
  31. for(int i=1;i<3;i++){
  32. max = max->max2(*(students+i));
  33. }
  34. max->show();
  35. for(int i=0;i<3;i++){
  36. delete students[i];
  37. }
  38. }

以下是代码运行结果

再见! Jack.
再见! Sue.
再见! Sam.
Sue 同学的语文成绩为92分,数学成绩为100分,英语成绩为95分,平均成绩95.7分
再见! Sue.
再见! Sam.
再见! Sue.
再见! Jack.

Sue 同学的语文成绩为92分,数学成绩为100分,英语成绩为95分,平均成绩95.7分
再见! Jack.
再见! Sue.
再见! Sam.
请按任意键继续. . .

从结果中我们可以看出,当我们使用fun1()中栈对象的时候创建并销毁了3个临时对象。对于大量的数据,创建对象和内容复制的时间浪费是相当大的。对于fun2()来说当我们创建对象成功后,并不需要去赋值内容,而仅仅是将引用传递给数组保存即可。但是要注意的是,堆中分配的数据一定要回收内存。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注