类模板的简单应用(用于存储不同类型数据的类容器)
类模板应用
explicit
explicit
是一个关键字,用于指定该构造函数是显式构造函数。在C++中,当一个类的构造函数只有一个参数时,它可以被用于隐式类型转换,这可能会导致意想不到的行为和潜在的错误。为了避免这种情况,可以使用 explicit
关键字来声明该构造函数,表示禁止隐式类型转换,只能显式地调用该构造函数来创建对象。
#include <iostream>
class MyClass {
public:
explicit MyClass(int x) {
std::cout << "Explicit constructor called with " << x << std::endl;
}
};
void func(MyClass obj) {
std::cout << "Function called" << std::endl;
}
int main() {
// 显式调用
MyClass obj1(10);
// 隐式调用,会触发显式构造函数,因为 MyClass 只有一个参数的构造函数,并且使用了 explicit 关键字
// MyClass obj2 = 20; // 编译错误,禁止隐式类型转换
MyClass obj3 = MyClass(20); // 显式调用
// 隐式调用,会触发隐式构造函数
func(30); // 隐式调用构造函数,然后调用函数
return 0;
}
必须显式的去写一句实例化的语句才能进行构造。
知道这个explicit关键字之后开始应用。
代码
设计一个数组模板类(MyArray),完成对不同类型元素的管理
#pragma once
template<class T>
class MyArray
{
public:
explicit MyArray(int capacity)
{
this->m_Capacity = capacity;
this->m_Size = 0;
// 如果 T 是对象,那么这个对象必须提供默认的构造函数
pAddress = new T[this->m_Capacity];
}
// 拷贝构造
MyArray(const MyArray& arr)
{
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < this->m_Size; i++)
{
this->pAddress[i] = arr.pAddress[i];
}
}
// 重载[] 操作符 arr[0]
T& operator [](int index)
{
return this->pAddress[index];
}
// 尾插法
void push_back(const T& val)
{
if (this->m_Capacity == this->m_Size)
{
return;
}
this->pAddress[this->m_Size] = val;
this->m_Size++;
}
void pop_back()
{
if (this->m_Size == 0)
{
return;
}
this->m_Size--;
}
// 获取大小的 const 成员函数
int getSize() const
{
return this->m_Size;
}
// 析构
~MyArray()
{
if (this->pAddress != nullptr)
{
delete[] this->pAddress;
this->pAddress = nullptr;
this->m_Capacity = 0;
this->m_Size = 0;
}
}
private:
T* pAddress; // 指向一个堆空间,这个空间存储真正的数据
int m_Capacity; // 容量
int m_Size; // 大小
};
首先实现的是构造函数,规定好必须显式的声明实例化,一个是为了隐式转换专门构造的一种方法,但其实这个过程并不是计算机进行的隐式,因为我们有专门的代码去编译。还有一个就是拷贝构造。
T& operator [](int ind) {
return this->ptr[ind];
}
void push_back(const T& ele) {
if (this->capacity == this->Msize) {
return;
}
this->ptr[this->Msize] = ele;
this->Msize++;
}
void pop_back() {
if (this->Msize == 0) {
return;
}
this->Msize--;
}
int get_size() {
return this->Msize;
}
~MyArray() {
if (this->ptr != NULL) {
delete []this->ptr;
this->pAddress = NULL;
this->capacity = 0;
this->Msize = 0;
}
}
这段代码里实现了入队和出队的功能,并且将之前学的重载操作符也用上了。测试代码里我们试图调用多个构造函数去理解代码的过程。
#include <iostream>
#include "MyArray.hpp"
using namespace std;
class Person {
public:
Person(){}
Person(string name, int age) {
this->name = name;
this->age = age;
}
public:
string name;
int age;
};
void PrintArrayInt(MyArray<int>& arr) {
for (int i = 0; i < arr.get_size(); i++) {
cout << arr[i] << " ";
}
cout << endl;
}
void PrintArrayPerson(MyArray<Person>& arr) {
for (int i = 0; i < arr.get_size(); i++) {
cout << "姓名:" << arr[i].name << " 年龄: " << arr[i].age << endl;
}
cout << endl;
}
int main() {
MyArray<int> ArrayInt(10); //通过显式转换
for (int i = 0; i < 9; i++)
{
ArrayInt.push_back(i);
}
ArrayInt.push_back(127);
PrintArrayInt(ArrayInt);
Person p1("regina", 23);
MyArray<Person> ArrayPerson(p1);//通过我们构造好的隐式转换
Person p2("ivanlee", 20);
Person p3("daji", 18);
Person p4("dianwei", 15);
Person p5("paofu", 24);
ArrayPerson.push_back(p2);
ArrayPerson.push_back(p3);
ArrayPerson.push_back(p4);
ArrayPerson.push_back(p5);
PrintArrayPerson(ArrayPerson);
return 0;
}
本文来自博客园,作者:ivanlee717,转载请注明原文链接:https://www.cnblogs.com/ivanlee717/p/18169832