编写拷贝构造函数(Copy Constructor)和赋值运算符(Assignment Operator)的测试用例是确保对象正确复制和赋值的关键步骤。这有助于避免常见的资源泄露、重复释放、自赋值等问题。以下是一些基本的指导原则和示例,用于编写这些测试用例。
拷贝构造函数的测试用例
拷贝构造函数是当一个对象被另一个同类型对象初始化时调用的构造函数。其目的是创建一个新对象,作为现有对象的一个深拷贝(或浅拷贝,取决于对象的性质)。
测试用例:
基本拷贝:
创建一个对象,并用其初始化另一个对象。
检查两个对象是否相等(内容相同),且修改一个对象不会影响另一个对象。
自拷贝:
用对象自身初始化一个新对象。
确保这不会导致无限递归或破坏原始对象。
动态内存管理:
如果对象包含动态分配的内存(如指针成员),确保拷贝后两个对象独立管理各自的内存。
示例代码(C++):
cpp
复制
class MyClass {
public:
int* data;
MyClass(int value) : data(new int(value)) {}
MyClass(const MyClass& other) : data(new int(*other.data)) {} // 拷贝构造函数
~MyClass() { delete data; }
// 假设有必要的比较函数等...
};
// 测试用例
void testCopyConstructor() {
MyClass obj1(10);
MyClass obj2 = obj1; // 使用拷贝构造函数
assert(*obj1.data == *obj2.data); // 基本拷贝测试
*obj1.data = 20;
assert(*obj1.data != *obj2.data); // 修改一个对象不应影响另一个
}
赋值运算符的测试用例
赋值运算符(=)用于将一个对象的值赋给另一个已存在的同类型对象。
测试用例:
基本赋值:
创建一个对象,并将其值赋给另一个已存在的对象。
检查赋值后,接收值的对象是否包含了正确的值。
自赋值:
将对象赋值给它自己。
确保对象的状态没有改变,且没有资源泄露或破坏。
动态内存管理:
如果对象包含动态分配的内存,确保赋值后旧内存被正确释放,新内存被正确分配。
示例代码(C++):
cpp
复制
class MyClass {
public:
int* data;
MyClass(int value) : data(new int(value)) {}
MyClass& operator=(const MyClass& other) {
if (this != &other) { // 自赋值检查
delete data; // 释放旧内存
data = new int(*other.data); // 分配新内存
}
return *this;
}
~MyClass() { delete data; }
// 假设有必要的比较函数等...
};
// 测试用例
void testAssignmentOperator() {
MyClass obj1(10);
MyClass obj2(20);
obj2 = obj1; // 使用赋值运算符
assert(*obj2.data == *obj1.data); // 基本赋值测试
MyClass obj3(30);
obj3 = obj3; // 自赋值测试
assert(*obj3.data == 30); // 确保自赋值后对象状态未变
}
通过这些测试用例,你可以确保你的拷贝构造函数和赋值运算符按预期工作,并避免了常见的错误。