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();
}

运行结果:

这样程序才算是完整了。

相关推荐
钮钴禄·爱因斯晨8 分钟前
C语言 | 函数核心机制深度解构:从底层架构到工程化实践
c语言·开发语言·数据结构
wkj00110 分钟前
php中array($this, ‘loadClass‘)表示啥意思?
android·开发语言·php
Stuomasi_xiaoxin10 分钟前
服务器重装后如何“复活”旧硬盘上的 Anaconda 环境?—— 一次完整的排错与恢复记录
开发语言·python·github
乌萨奇也要立志学C++43 分钟前
【C++详解】STL-list模拟实现(深度剖析list迭代器,类模板未实例化取嵌套类型问题)
c++·list
presenttttt1 小时前
用Python和OpenCV从零搭建一个完整的双目视觉系统(四)
开发语言·python·opencv·计算机视觉
每日出拳老爷子1 小时前
[C#] 使用TextBox换行失败的原因与解决方案:换用RichTextBox的实战经验
开发语言·c#
半桔1 小时前
【Linux手册】从接口到管理:Linux文件系统的核心操作指南
android·java·linux·开发语言·面试·系统架构
闻缺陷则喜何志丹1 小时前
【前缀和 BFS 并集查找】P3127 [USACO15OPEN] Trapped in the Haybales G|省选-
数据结构·c++·前缀和·宽度优先·洛谷·并集查找
nightunderblackcat1 小时前
新手向:实现ATM模拟系统
java·开发语言·spring boot·spring cloud·tomcat·maven·intellij-idea
开开心心就好1 小时前
电脑息屏工具,一键黑屏超方便
开发语言·javascript·电脑·scala·erlang·perl