C++ 指针作为类的数据成员

当指针作为类的数据成员时,要想打印当前创建的对象的值有以下两种方法:

1.让指针指向当前所创建的对象

(1)在成员初始化列表进行指针指向

cpp 复制代码
#include<iostream>
using namespace std;
class A
{
public:
	A(const char *str= ""):m_str(str) //指针str接收了helloworld这个字符串的首地址
	{

	}
	void Print()
	{
		cout << m_str << endl;
	}
private:
	char* m_str;
};
void main()
{
	A a("Helloworld");
	a.Print();
}

这样是不可行的,不可以进行编译:

(2)在构造函数内部进行指针指向

cpp 复制代码
using namespace std;
class A
{
public:
	A(const char *str= "") //指针str接收了helloworld这个字符串的首地址
	{
		m_str = str;
	}
	void Print()
	{
		cout << m_str << endl;
	}
private:
	const char* m_str;  //如果要用m_str指针指向str指针,那么m_str必须也为const类型
};
void main()
{
	A a("Helloworld");
	a.Print();
}

运行结果:

这样虽然可以输出m_str所指向的对象的值,但是不能修改它的值。当指针作为类的数据成员时,以下方法则可以做到既能输出当前所创建的对象的值,又可以修改它的值。

2.让指针所指向的内存单元中存储所创建的对象的值

输出指针所指向的内存单元中存储所创建的对象的值:

cpp 复制代码
class A
{
public:
	A(const char* str = "")  //指针str接收了helloworld这个字符串的首地址
	{
		m_str = (char*)malloc((strlen(str) + 1) * sizeof(char));
		strcpy_s(m_str, strlen(str) + 1, str);//把str拷贝strlen(str) + 1个给m_str
	}
	void Print()
	{
		cout << m_str << endl;//让m_str这个指针所指向的内存单元中存储helloworld,而不是让m_str指向helloworld
	}
private:
	char* m_str;
};
void main()
{
	A a("Helloworld");
	a.Print();
}

运行结果:

修改指针所指向的内存单元中存储所创建的对象的值:

cpp 复制代码
class A
{
public:
	A(const char* str = "")  //指针str接收了helloworld这个字符串的首地址
	{
		m_str = (char*)malloc((strlen(str) + 1) * sizeof(char));
		strcpy_s(m_str, strlen(str) + 1, str);//把str拷贝strlen(str) + 1个给m_str
		m_str[3] = '8';
	}
	void Print()
	{
		cout << m_str << endl;//让m_str这个指针所指向的内存单元中存储helloworld,而不是让m_str指向helloworld
	}
private:
	char* m_str;
};
void main()
{
	A a("Helloworld");
	a.Print();
}

运行结果:

这种方法与第一种方法的区别是:

第一种方法通过指针指向所创建对象的值,从而输出它的值。

第二种方法是通过开辟了一段连续的动态内存单元,将所创建的对象的值存放到这一段内存单元中

【注意】由于malloc所开辟的空间是在堆区,那么就在使用完之后必须要释放掉。

什么时候释放在堆上所开辟的内存空间?

既然在构造函数中开辟了空间,那么就要在析构函数中释放空间。虽然在没有提供析构函数的情况下系统会自动提供一个默认的析构函数,但是由于该段内存空间是在堆上开辟,所以系统提供的析构函数不能满足要求,所以需要程序员把析构函数写出来。
析构函数什么时候必须要程序员定义?

如果有指针作为当前类的数据成员,则一定需要在当前类中自己定义析构函数。

如下:

cpp 复制代码
class A
{
public:
	A(const char* str = "")  //指针str接收了helloworld这个字符串的首地址
	{
		m_str = (char*)malloc((strlen(str) + 1) * sizeof(char));
		strcpy_s(m_str, strlen(str) + 1, str);//把str拷贝strlen(str) + 1个给m_str
		m_str[3] = '8';
	}
	void Print()
	{
		cout << m_str << endl;//让m_str这个指针所指向的内存单元中存储helloworld,而不是让m_str指向helloworld
	}
	~A()
	{
		if (m_str != NULL)
		{
			free(m_str);
			m_str = NULL;
		}		
	}
private:
	char* m_str;
};
void main()
{
	A a("Helloworld");
	a.Print();
}

运行结果:

这样程序才算是完整了。

相关推荐
CodeCraft Studio14 分钟前
PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 Base64
开发语言·python·pdf·base64·aspose·aspose.pdf
零点零一15 分钟前
VS+QT的编程开发工作:关于QT VS tools的使用 qt的官方帮助
开发语言·qt
鹅毛在路上了2 小时前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg
John_ToDebug2 小时前
定制 ResourceBundle 的实现与 DuiLib 思想在 Chromium 架构下的应用解析
c++·chrome·ui
lingchen19062 小时前
MATLAB的数值计算(三)曲线拟合与插值
开发语言·matlab
gb42152873 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
一朵梨花压海棠go3 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
蒋星熠3 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
翻滚丷大头鱼3 小时前
Java 集合Collection—List
java·开发语言
小欣加油3 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展