【C++】模版的概念、使用方法和深入了解
模板是泛型编程的基础。所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式。模板分为模板函数和模板类。
模板函数
假设现在要实现一个比较两个数是否相等的重载函数。
bool IsEqual (int left, int right)
{
return left == right;
}
bool IsEqual (const string& left , const string& right)
{
return left == right;
}
void test1 ()
{
string s1 ("s1"), s2("s2");
cout<<IsEqual (s1, s2)<<endl;
cout<<IsEqual (1,1)<<endl;
}
从代码可以看出,如果我们要比较int和char类型需要分别编写程序来解决这两个问题,所以代码的重复度就会很高,所以C++中就引入了模版来解决这个问题。
模板形参的定义既可以使用class,也可以使用typename,含义是相同的。上面的问题就可以简化为如下的代码:
template<class T>
bool IsEqual(const T& left, const T& right)
{
return left == right;
}
void test1 ()
{
string s1 ("s1"), s2("s2" );
cout<<IsEqual (s1, s2)<<endl ;
cout<<IsEqual (1,1)<<endl;
}
对于T的类型,编译器自己会通过推演得到T的类型,从而做出应有的处理。
在这,重点分享下模版的深入知识。
template<typename T>
class SeqList
{
public:
SeqList()
:_array(NULL)
, _size(0)
, _capacity(0)
{}
~SeqList()
{
if (_array)
{
delete[] _array;
}
}
SeqList(const SeqList<T>& s)
{
_array = new T[s._size];
//memcpy(_array, s._array, sizeof(T)*s._size);
for (size_t i = 0; i < s._size; i++)//根据size的大小来,原空间多大,同样拷贝多大的空间
{
_array[i] = s._array[i];
}
_size = s._size;
_capacity = s._capacity;
}
SeqList<T>& operator=(SeqList<T> s)
{
swap(_array, s._array);
swap(_size, s._size);
swap(_capacity, s._capacity);
return *this;
}
void PushBack(const T& x)
{
_CheckCapacity();
_array[_size++] = x;
}
void Print()
{
for (int i = 0; i < _size; ++i)
{
cout << _array[i] << " ";
}
cout << endl;
}
void Reserve(size_t x)
{
_CheckCapacity(x);
}
T& operator[](size_t index)
{
assert(index < _size);
return _array[index];//如果不用引用,那么传过来的是一块临时空间,只是将临时空间的值给覆盖了,如果使用引用那么就是把对应的空间给出来,赋值的时候直接在原基础上改动
}
protected:
void _CheckCapacity(size_t n)
{
if (n > _capacity)
{
_capacity = 2 * _capacity + 3 > n ? 2 * _capacity + 3 : n;
/*_array = (T*)realloc(_array, sizeof(T)*_capacity);*/
T* tmp = new T[_capacity];
if (_array)
/*memcpy(tmp, _array, sizeof(T)*_size);*/
for (size_t i = 0; i < _size; i++)
{
tmp[i] = _array[i];
}
delete[] _array;
_array = tmp;
}
}
private:
T* _array;
size_t _size;
size_t _capacity;
};
//template<typename T> //在模版内声明,在模版外定义与C++代码写顺序表的区别
//void SeqList<T>::PushBack(const T& x)//作用域要写类型名,而不是类名
//{
//
//}
void test1()
{
SeqList<int>s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
s1.Print();
SeqList<string> s2;
s2.PushBack("xxx");
s2.PushBack("xxx");
s2.PushBack("xxx");
s2.PushBack("xxx");
s2.PushBack("xxx");
s2.Print();
SeqList<string> s3(s2);
s3.Print();
SeqList<string> s4;
s4.PushBack("yyy");
s4 = s3;
s4.Print();
//string* p1 = (string*)malloc(sizeof(string));//指向的是字符串类,字符串类里面不仅仅只包含了字符串指针,还有_size,_capacity等内容
//string* p2 = new string;
//*p1 = "sss";
//*p2 = "sss";
}
int main()
{
test1();
system("pause");
return 0;
}
转载于:https://blog.51cto.com/10740329/1750293