加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 经验 > 正文

C++带有指针成员的类处理方式详解

发布时间:2020-12-24 07:57:47 所属栏目:经验 来源:网络整理
导读:副标题#e# 在一个类中,如果类没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存。但是如果一个类带了指针成员,那么需要我们自己来写一个析构函数来管理内存。在c++ primer 中写到,如果一个类需要我们自己写析构函数,那么这个类,也
副标题[/!--empirenews.page--]

在一个类中,如果类没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存。但是如果一个类带了指针成员,那么需要我们自己来写一个析构函数来管理内存。在<<c++ primer>> 中写到,如果一个类需要我们自己写析构函数,那么这个类,也会需要我们自己写拷贝构造函数和拷贝赋值函数。

析构函数:

我们这里定义一个类HasPtr,这个类中包含一个int 类型的指针。然后定义一个析构函数,这个函数打印一句话。

HasPtr.h 类的头文件

#pragma once
#ifndef __HASPTR__
#define __HASPTR__

class HasPtr
{
public:
 HasPtr(int i,int *p);
 //HasPtr& operator=(HasPtr&);
 //HasPtr(const HasPtr&);
 ~HasPtr();
 int get_ptr_value();
 void set_ptr_value(int *p);
 int get_val();
 void set_val(int v);
private:
 int val;
 int *ptr;
};

#endif // !__HASPTR__

HasPtr.cpp 类的实现

#include "stdafx.h"

#include <iostream>
#include "HasPtr.h"

using namespace std;

HasPtr::HasPtr(int i,int *p)
{
 val = i;
 ptr = p;
}

int HasPtr::get_ptr_value()
{
 return *ptr;
}

void HasPtr::set_ptr_value(int *p)
{
 ptr = p;
}

int HasPtr::get_val()
{
 return val;
}

void HasPtr::set_val(int v)
{
 val = v;
}

HasPtr::~HasPtr()
{
 cout << "destructor of HasPtr " << endl;
}

ClassWithPointer 类,包含main入口,HasPtr在stack上。

// ClassWithPointer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "HasPtr.h"
using namespace std;

int main()
{
 int temp = 100;
 HasPtr ptr(2,&temp);
 cout << ptr.get_ptr_value() << endl;
 cout << ptr.get_val() << endl;
 system("PAUSE");
 system("PAUSE");
 return 0;
}

执行该入口方法,发现最后还是打印了析构函数这句话,OK,在main 方法中,stack上定义了一个HasPtr,在main方法退出前,析构函数自动调用了。

如果将HasPtr改为动态对象,也就是放在堆上呢?

ClassWithPointer 类,包含main入口,HasPtr在heap上。

// ClassWithPointer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "HasPtr.h"
using namespace std;

int main()
{
 int temp = 100;
 //HasPtr ptr(2,&temp);
 HasPtr *ptr = new HasPtr(2,&temp);
 cout << ptr->get_ptr_value() << endl;
 cout << ptr->get_val() << endl;
 system("PAUSE");
 return 0;
}

执行一下,发现析构函数没有调用。OK,我们在return 0前面添加一个delete ptr; 析构函数执行了。

所以,这里有两个结论:

  • 当一个对象在stack 上时,析构函数自动调用。
  • 当一个对象在heap上时,需要调用delete 语句,析构函数才会被执行。

现在在析构函数中调用delete 语句来删除指针成员。

头文件不变,HasPtr.cpp 文件代码如下:

 #include "stdafx.h"

#include <iostream>
#include "HasPtr.h"

using namespace std;

HasPtr::HasPtr(int i,int *p)
{
 val = i;
 ptr = p;
}

int HasPtr::get_ptr_value()
{
 return *ptr;
}

void HasPtr::set_ptr_value(int *p)
{
 ptr = p;
}

int HasPtr::get_val()
{
 return val;
}

void HasPtr::set_val(int v)
{
 val = v;
}

HasPtr::~HasPtr()
{
 cout << "destructor of HasPtr " << endl;
 delete ptr;
}

 ClassWithPointer 代码如下:

// ClassWithPointer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "HasPtr.h"
using namespace std;

int main()
{
 int temp = 100;
 HasPtr ptr(2,&temp);
 cout << ptr.get_ptr_value() << endl;
 cout << ptr.get_val() << endl;
 system("PAUSE");
 return 0;
}

执行一下,正常打印结束后,抛出错误:

C++带有指针成员的类处理方式详解

这里说明delete 不能删除stack 上的指针值。

现在在ClassWithPointer传入一个动态指针来测试一下。

// ClassWithPointer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "HasPtr.h"
using namespace std;

int main()
{
int temp = 100;
HasPtr ptr(2,&temp);
cout << ptr.get_ptr_value() << endl;
cout << ptr.get_val() << endl;
system("PAUSE");
return 0;
}

执行后析构函数正常运行。所以这里有两个结论:

  • delete 语句不能删除stack 上的指针值。
  • delete 语句只能删除heap上的指针值,也就是new 出来的对象。 

默认拷贝构造函数和默认赋值操作:

这里我们调用默认的构造函数和默认的赋值操作,看看会出现什么,为了方便查看,我在析构函数中打印了当前对象的地址,以及在main方法中打印了对象地址,这样就可以看到哪个对象调用了析构函数:

HasPtr.cpp 代码如下:

#include "stdafx.h"

#include <iostream>
#include "HasPtr.h"

using namespace std;

HasPtr::HasPtr(int i,int *p)
{
 val = i;
 ptr = p;
}

int HasPtr::get_ptr_value()
{
 return *ptr;
}

void HasPtr::set_ptr_value(int *p)
{
 ptr = p;
}

int HasPtr::get_val()
{
 return val;
}

void HasPtr::set_val(int v)
{
 val = v;
}

HasPtr::~HasPtr()
{
 cout << "destructor of HasPtr " << this << endl;
 delete ptr;
}

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读