###触发断言
在做老师布置的类模板作业是将类保存到自己写的 Vector 容器中时触发断言。一开始以为哪里写错了,断点调试发现是我写的学生类 Student 的析构函数在关闭程序的时候触发的断言。
之后将 Student 类的析构函数中的释放内存注释掉以后,虽然程序正常运行到正常结束没有在出问题,但是我还有觉得这样会有内存泄露。我找到VS自带的内存泄漏的工具,检查以后果然是有内存泄露。
在之后我就开始各种调试各种博客搜索引擎找解决办法,结果当然是没有我这种情况。找了几个小时也没有解决,之后准备去问问老师看看。在问老师之前决定吧剩下的作业做完再去,结果神奇的事情发生了,断言居然消失了。仔细检查了下代码,我只做了一个操作,重写了拷贝构造函数 operator= ,仔细想想这个情况应该和深拷贝和浅拷贝的问题,我没有写自定义拷贝函数的时候出现断言,应该就是浅拷贝造成的。
在此记录自己遇到的一点小问题。
#####触发断言的代码
Vector.h
#pragma once
#include <iostream>
using namespace std;
template <typename T>
class Vector
{
public:
Vector(int size = 128); //构造函数
Vector(const Vector& object); //拷贝构造函数
//Vector<int> a1; a1[0]
T& operator[](int index); // []重载
//实现=操作符重载
Vector& operator=(const Vector& object);
friend ostream& operator<< <T>(ostream& out, const Vector<T>& object);
int GetLength()const; //获取内部存储的元素个数
~Vector(); //析构函数
private:
T* m_base;
int m_len;
};
template <typename T>
ostream& operator<<(const ostream& out,const Vector<T>& object);
Vector.cpp
#include "Vector.h"
template<typename T>
Vector<T>::Vector(int size)
{
if (size > 0)
{
this->m_len = size;
this->m_base = new T[size];
}
else
{
this->m_len = 0;
this->m_base = NULL;
}
}
template<typename T>
Vector<T>::Vector(const Vector<T>& object)
{
//根据传入的对象元素个数分配空间
this->m_len = object.m_len;
this->m_base = new T[m_len];
//数据拷贝
for (int i = 0; i < m_len; i++)
{
m_base[i] = object.m_base[i];
}
}
template<typename T>
T& Vector<T>::operator[](int index)
{
return m_base[index]; //等同return *(m_base+index)
}
template<typename T>
Vector<T>& Vector<T>::operator=(const Vector<T>& object)
{
if (m_base != NULL)
{
delete[] m_base;
this->m_base = NULL;
this->m_len = 0;
}
//根据传入的对象元素个数分配空间
this->m_len = object.m_len;
this->m_base = new T[m_len];
//数据拷贝
for (int i = 0; i < m_len; i++)
{
m_base[i] = object.m_base[i];
}
return *this;
}
template<typename T>
int Vector<T>::GetLength() const
{
return m_len;
}
template<typename T>
Vector<T>::~Vector()
{
//cout << __FUNCTION__ << endl;
if (this->m_base != NULL)
{
delete[] m_base;
this->m_base = NULL;
this->m_len = 0;
}
}
template<typename T>
ostream& operator<<(ostream& out, const Vector<T>& object)
{
for (int i = 0; i < object.m_len; i++)
{
out << object.m_base[i] << " ";
}
out << endl;
return out;
}
Student.h
#pragma once
#include <iostream>
using namespace std;
class Student {
public:
Student(int _age = 0, const char* _name = NULL);
void print() const;
char& GetPname()const;
~Student();
//Student(const Student& student);
//Student& operator=(Student& object);
friend ostream& operator<<(ostream& out, const Student& object);
private:
int age;
char* pname;
};
Student.cpp
#include "Student.h"
ostream& operator<<(ostream& out, const Student& object)
{
out << "(" << object.pname << "," << object.age << ")";
return out;
}
Student::Student(int _age, const char* _name)
{
if (_name != NULL)
{
this->age = _age;
this->pname = new char[strlen(_name) + 1];
strcpy_s(this->pname, strlen(_name) + 1, _name);
}
else
{
this->age = 0;
this->pname = NULL;
}
}
void Student::print() const
{
cout << pname << "," << age << endl;
}
char& Student::GetPname() const
{
return *pname;
}
Student::~Student()
{
//cout << "调用Student析构函数: " << __FUNCTION__ << endl;
if (this->pname != NULL)
{
delete[] this->pname;
this->pname = NULL;
}
}
// Student::Student(const Student& student)
// {
// if (this->pname == NULL)
// {
// this->pname = new char[strlen(student.pname) + 1];
// strcpy_s(this->pname, strlen(student.pname) + 1, student.pname);
// this->age = student.age;
// }
// else
// {
// delete[] this->pname;
// this->pname = NULL;
// this->pname = new char[strlen(student.pname) + 1];
// strcpy_s(this->pname, strlen(student.pname) + 1, student.pname);
// this->age = student.age;
// }
//
// }
//
// Student& Student::operator=(Student& object)
// {
// //cout << "调用自定义拷贝构造函数: " <<__FUNCTION__ << endl;
// if (this->pname == NULL)
// {
// this->age = object.age;
// this->pname = new char[strlen(object.pname) + 1];
// strcpy_s(this->pname, strlen(object.pname) + 1, object.pname);
// }
// else
// {
// delete[] this->pname;
// this->pname = NULL;
// this->age = object.age;
// this->pname = new char[strlen(object.pname) + 1];
// strcpy_s(this->pname, strlen(object.pname) + 1, object.pname);
// }
// return *this;
// }
测试代码
int main(void)
{
Student s1(18, "Rook老师");
Student s2(19, "Martin老师");
Vector<Student> studentVector(2);
studentVector[0] = s1;
studentVector[1] = s2;
cout << studentVector << endl;
cout << "测试自定义拷贝构造函数:\n";
Student s3(s2);
cout << s3;
s3 = s1;
cout << s3 ;
}
去除我注释掉的自定义拷贝构造函数就不会再报错。