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

运行结果:

这样程序才算是完整了。

相关推荐
小叮当爱咖啡14 分钟前
Day3.参数+Prompt三板斧
开发语言·python·prompt
菜冻鱼21 分钟前
Python-pandas-索引与筛选
开发语言·笔记·python·numpy·pandas·学习方法
我想走路带风33 分钟前
各自缓冲及实现
c++
鹿角片ljp1 小时前
Java面试复盘(二):String不可变、字符串常量池与字符串拼接
开发语言·python
小秋求学记.2 小时前
PHP安全漏洞实战:从环境配置到RCE攻击
开发语言·php
阿米亚波2 小时前
【C/C++包管理器】vcpkg(by microsoft)
c语言·c++·git·vscode·microsoft·github·vcpkg
看浪的路人2 小时前
第3讲:代码补全引擎
开发语言·windows·python
SNAKEpc121382 小时前
OpenGL(十一)- 变换管线
c语言·c++·算法·矩阵·图形渲染
小小龙学IT2 小时前
Day 26-27 项目实战:从零构建一个高并发聊天室(epoll + 线程池)
linux·服务器·c语言·开发语言·网络
牢姐与蒯3 小时前
c++高级数据结构之图(基本概念,存储结构,BFS,DFS,最小生成树)
数据结构·c++·