c++自己实现一个数组类


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
using namespace std;

class Animal
{
public:
Animal()
{
a = 1;
b = 2;
cout << "Animal()..." << endl;
}
Animal(const Animal &animal)
{
a = animal.a;
b = animal.b;
cout << "Animal(const Animal &animal)" << endl;
}
Animal &operator=(const Animal &animal)
{
a = animal.a;
b = animal.b;
cout << "Animal &operator=(const ...)" << endl;
return *this;
}
private:
int a;
int b;
};

template<class T>
class MyArray
{
public:
friend ostream &operator<<<T>(ostream &out, MyArray<T> &a);
MyArray(int size)
{
this->size = size;
this->len = 0;
point = new T[size];//new一个size长度的数组
memset(point, 0, size);//把数组清零
}
MyArray(const MyArray<T> &array)//在类模板中,类模板中的方法包含本类的类型是可以省略<T>,但在类外不可以,因此为了防止发生错误,在此规定,都要加上<T>
{
if (array.len == 0)//拷贝构造是这个对象还没有存在,需要拷贝构造出来,而赋值函数即重写=号操作符使这个对象已经存在了,两者完全不一样
{
this->size = array.size;
this->len = array.len;
point = new T[size];
memset(point, 0, size);
}
else
{
this->size = array.size;
this->len = array.len;
point = new T[size];//这儿才是调用了类型T的构造函数,没有调用拷贝构造函数,拷贝构造函数使用情景一般是两点:1.初始化时用对象进行初始化 2.存在匿名对象时,构造匿名对象需要用到拷贝构造函数
memset(point, 0, size);
for (int i = 0; i < len; i++)
{
//数组元素的类型可以是类,即数组元素为对象,这儿是用=号直接赋值的,因此这儿是调用了赋值函数,并没有调用拷贝构造函数
point[i] = array.point[i];
}
}
}
void setData(int len)
{
this->len = len;
for (int i = 0; i < len; i++)
{
point[i] = i + 1;
}

}

void putData(const T &data)
{
len = len + 1;
point[len] = data;//这儿没有调用拷贝构造函数,只是调用赋值函数,视频上讲的是错误的
}

T &operator[](int index)
{
return point[index];
}
//重写等号操作符,返回对象本身,则返回的类型写法MyArray<T>
MyArray<T> &operator=(const MyArray<T> &array)
{
//重写赋值操作符时,先拷贝是不是自己对自己赋值,然后判断成员指针指向的数组是否有元素
if (this == &array)
{
return *this;
}
else if (array.len == 0)
{
this->size = array.size;
this->len = array.len;
delete[] point;
point = new T[size];
memset(point, 0, size);
return *this;
}
else
{
this->size = array.size;
this->len = array.len;
delete[] point;
point = new T[size];
memset(point, 0, size);
for (int i = 0; i < len; i++)
{
point[i] = array.point[i];
}
return *this;
}
}
~MyArray()
{
delete[] point;
}
private:
//数组可以容下个多少元素
int size;
//当前数组内有多少元素
int len;
//指向数组的指针
T *point;
};

template<class T>
ostream &operator<<(ostream &out, MyArray<T> &a)//这儿具体的类型需要进入类模板的私有空间进行类型赋值,但这时类外,显然不可以,因此需要声明为友元函数
{
for (int i = 0; i < a.len; i++)
{
out << a[i] << " ";
}
return out;
}


class Test
{

public:
Test():a(10), b(2)
{
cout << "Test()" << endl;
}
Test(int a):a(10), b(a)
{
cout << "Test(int a)" << endl;
}
private:
//什么时候必须要使用初始化列表
//1.成员变量为const修饰的变量
const int a;
//2.成员变量为引用类型变量
const int &b;
};

//c++11新特性,对临时变量取引用int &&a
void funcTest1(int &&a)
{
cout << a << endl;
}
void funcTest2(const int &a)
{
cout << a << endl;
}

int main()
{
MyArray<int> a1(10);
MyArray<int> a2(20);
a1.setData(10);
a2 = a1;
cout << a1 << endl;
cout << a2 << endl;

Test t;//通过无参构造函数创建对象,这种形式的一定不能写成Test t()这种形式
Test t1(1);

funcTest1(100);
funcTest2(200);

MyArray<Animal> a3(10);
Animal animal;
a3.putData(animal);
return 0;
}

猜你喜欢

转载自blog.csdn.net/tulipless/article/details/80939911