提示:文章
文章目录
- 前言
- 一、背景
- 二、过程
- 2.1 编写代码
- 2.3 问题探究
- 总结
前言
前期疑问:
本文目标:
一、背景
最近突然看到hpp文件,查了百度也没有hpp文件怎么写的说明,自己就试着写了下,写成功了。
而且基于写hpp文件还串联了其他的知识点。下面整理一下测试代码
二、过程
2.1 编写代码
// main.cpp文件
#include <cstdio>
#include "hppTest.hpp"
void TestMemory(HppTest &hppTest)
{
for (unsigned int i = 0; i < 1000; i++) {
char* str = hppTest.hppTestGetStr();
printf("%d, %s\n", i, str);
}
}
void TestMemory2()
{
for (unsigned int i = 0; i < 100; i++) {
HppTest hppTest;
char* str = hppTest.hppTestGetStr();
printf("%d, %s\n", i, str);
}
}
void TestCopyConstruct(HppTest& hppTest)
{
/*
* 报错Call to deleted constructor of 'HppTest'
* 'HppTest' has been explicitly marked deleted here
* 这边报错hppTest对象不能被拷贝构造。从报错语句跳转到类中,
* 跳转到HppTest(const HppTest &x) = delete;语句,
* 也验证了HppTest hppTest2 = hppTest;写法是调用拷贝构造函数,因为hppTest2还不存在
*/
HppTest hppTest2 = hppTest; //拷贝构造函数
/*
* 报错Overload resolution selected deleted operator '='
* candidate function has been explicitly deleted
* 根据错误跳转到HppTest& operator = (const HppTest &x) = delete;语句、
* 也验证了hppTest3 = hppTest;是调用赋值构造函数
*/
HppTest hppTest3;
hppTest3 = hppTest;
}
int main()
{
printf("hppTest\n");
HppTest hppTest;
int num = hppTest.hppTestFunc();
printf("num: %d\n", num);
// 构造内存泄露的情况,但是没有成功,原因是我的申请内存是在实例化对象的时候申请的,
// 在for循环中并不会再次申请,同样就不会释放,for循环多少次都是一样的。修改成代码TestMemory2
TestMemory(hppTest);
// 在for循环中实例化对象,不断申请内存释放内存
/*
* 按照预期内存泄露,运行第6次就内存泄漏了。基于析构函数中delete被注释
* terminate called after throwing an instance of 'std::bad_alloc'
* what(): std::bad_alloc
* 下面放开析构函数中的delete释放内存代码,再次验证
* 执行1000次也没内存泄露,所以hpp中的析构函数有作用,析构函数中的delete释放内存有作用。
*/
TestMemory2();
TestCopyConstruct();
return 0;
}
// HppTest.hpp文件
#ifndef TESTPROJ_LOCAL_WITHOUT_LIBRARY_HPPTEST_H
#define TESTPROJ_LOCAL_WITHOUT_LIBRARY_HPPTEST_H
#include <stdlib.h>
#include "string.h"
class HppTest {
public:
HppTest() : num(16), array(nullptr)
{
//array = (char*)malloc(sizeof(char) * 15);
array = new char[1500000000];
}
~HppTest()
{
delete[] array;
printf("array is released\n");
}
// 禁止复制构造函数
HppTest(const HppTest &x) = delete;
HppTest &operator=(const HppTest &x) = delete;
int hppTestFunc()
{
return num;
}
char* hppTestGetStr()
{
memcpy(array, "hello world", sizeof(char) * 15);
return array;
}
private:
int num;
char* array;
};
#endif //TESTPROJ_LOCAL_WITHOUT_LIBRARY_HPPTEST_H
// 上述代码写的过程中遇到的几个问题
/*
* 1、new申请空间的写法不知道
* 2、在纠结hpp文件要不要写析构函数,答案是可以写的
* 3、完全不知道怎么写拷贝构造函数和复制构造函数。
* 4、照着自己写的文章写了拷贝构造函数和复制构造函数,写了=delete禁用,但是也写了花括号,报错了,正确的是写了=delete就不要写花括号了
* 5、写禁止拷贝的原因是类中有指针。但是是否是这样还需要确认一下。
* 6、想验证一下hpp文件的类的析构函数和内存释放是否有用描写了测试函数TestMemory和TestMemory2,从TestMemory函数到TestMemory2函数也加深了理解
* 7、验证写了禁用拷贝、复制构造函数后,是否会禁用拷贝和赋值,经过TestCopyConstruct函数演这个,确实禁用了拷贝和赋值构造函数。
* 8、c++初始化列表跟在构造函数后面,多个成员使用初始化李彪初始化时,使用【,】连接。
*/
// cmakelist.txt文件
include_directories(hppTest/HppTest.hpp)
add_executable(hppTest
hppTest/main.cpp)
上述代码运行结果【前提要把TestCopyConstruct函数注释掉,因为调用了拷贝赋值构造函数】
hppTest
num: 16
0, hello world
1, hello world
2, hello world
...
...
998, hello world
999, hello world
0, hello world
array is released
1, hello world
array is released
2, hello world
array is released
...
...
98, hello world
array is released
99, hello world
array is released
array is released
上面打印结果中最后一个array is released是因为释放main函数中的对象。
2.3 问题探究
// 上述代码写的过程中遇到的几个问题
/*
- 1、new申请空间的写法不知道
- 2、在纠结hpp文件要不要写析构函数,答案是可以写的
- 3、完全不知道怎么写拷贝构造函数和复制构造函数。
- 4、照着自己写的文章写了拷贝构造函数和复制构造函数,写了=delete禁用,但是也写了花括号,报错了,正确的是写了=delete就不要写花括号了
- 5、写禁止拷贝的原因是类中有指针。但是是否是这样还需要确认一下。
- 6、想验证一下hpp文件的类的析构函数和内存释放是否有用描写了测试函数TestMemory和TestMemory2,从TestMemory函数到TestMemory2函数也加深了理解
- 7、验证写了禁用拷贝、复制构造函数后,是否会禁用拷贝和赋值,经过TestCopyConstruct函数演这个,确实禁用了拷贝和赋值构造函数。
- 8、c++初始化列表跟在构造函数后面,多个成员使用初始化李彪初始化时,使用【,】连接。
*/
针对这个hpp文件的写法又收获了一波啊
总结
未完待续