我是靠谱客的博主 还单身水壶,最近开发中收集的这篇文章主要介绍学习笔记 C++ 动态数组类的声明,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

学习笔记  C++

第九章 群体类和群体数据的组织/ 9.2线性群体

C++动态数组类的声明

一  Array<T>& operator= (const Array<T>&rhs); / /重载"="使数组对象可以整体赋值

1.1为什么要重载"="

提示 若不对"="运算符进行重载,系统,会为其自动生成一个隐含的重载函数,该函数会分别对每个数据成员执行"="运算符。

一般而言,当对象需要通过显式定义的复制构造函数执行深复制时,也需要重载赋值运算符,执行类似的深复制操作。

细节 语法规定"=", "[]" ,"()","->"只能被重载为成员函数,而且派生类中的”="运算符函数总会隐藏基类中的"="运算符函数。

template<class T>

Array<T>&Array<T>: :operator= (const Array<T>& rhs) {

if (&rhs !=this) {

//如果本对象中数组大小与 rhs 不同,则删除数组原有内存,然后重新分配

If (size!=rhs.size){

  Delete []list;    //删除数组原有内存

  size=rhs.size;   //设置本对象的数组大小

  list=new T[size];   //重新分配 size 个元素的内存

}

//从对象 rhs 复制数组元素到本对象

for (int i=0;i<size;i++)

list[i]=rhs.list[i];

}

return *this;

}

二  T & operator [] (int i); //重载”[]”使 Array 对象可以起到 C++ 普通数组的作用

const T & operator [] (int i) const; / /" []"运算符针对 const 的重载

2.1针对 const 的重载

/*后置const是为了让常对象能调用这个成员函数(常对象只能调用常成员函数,不能调用普通成员函数)“const T*”表示,通过对象名创建数组后,通过对象名不能改变数组*/

  1. int sum (int a) 和 int sum (const int a);不是重载

  但是int sum (int* a) 和 int sum (const int* a);却是重载

  当使用引用传参时,有无const是不同的。使用指针传参时,指向const对象的指针和指向非const对象的指针做形参的函数是不同的。非指针和非引用就是相同的

  1. const对象才能调用const版本的function函数,而非const对象可以调用任意一种,通常非const对象调用不是const版本的function函数。
  2. 原因是:按照函数重载的定义,函数名相同而形参表有本质不同的函数称为重载。在类中,由于隐含的this形参的存在,const版本的 function函数使得作为形参的this指针的类型变为指向const对象的指针,而非const版本的使得作为形参的this指针就是正常版本的指针。此处是发生重载的本质。重载函数在最佳匹配过程中,对于const对象调用的就选取const版本的成员函数,而普通的对象调用就选取非const版 本的成员函数。

这就是运算符重载的意思,函数重载也是这样的。

编译器根据给定的不同参数来判定用哪个函数

2.2为什么要重载下标运算符”[]”

在main函数写a[i],编译器是不会把这里的a当作数组名list的,所以仅仅是写a[i]是无法调用数组元素的(编译器不认这种代码),只有重载了下标运算符“[ ]”,编译器才会把a[i]当成list[i];

简单的说,

  重载下标运算符,作用仅限于把“a[i]”转换成“list[i]”;

三  operator T* (); / /重载到 T* 类型的转换,使 Array 对象可以起到 C++ 普通数组的作用

operator const T* () const; / /到 T*类型转换操作符针对 const 的重载

3.1为什么要重载指针转换运算符 T*

为了说明重载指针转换运算符的必要性,先来看一看下面这段程序:

#include using namespace std;

void read (int *p, int n) {

 for (int i=0; i<n;i++)

cin>>p[i] ;

}

int main(){

 int a [10];

 read(a,10);

 return 0;

}

这里函数 read 的第一个形参是 mt 指针,而数组名是一个 int 型地址常量,类型恰 好是匹配的。如果希望在程序中像使用普通数组一样使用 Array 类的对象,将上述 mam 函数修改如下:

int main (){

 Array<int>a(10);

 read(a,10);

 return 0;

}

这回在调用 read 时会发现实参类型与形参类型不同,这时编译系统会试图进行自动类型转换:将对象名a转换为 int *类型。由于a是自定义的类类型对象,所以编译系统提供的自动转换功能当然无法实现这一转换,因此我们需要自行编写重 载的指针类型转换函数。

c++ 中,如果想将自定义类型T的对象隐含或显式地转换为S类型,可以将 operator S定义为T的成员函数。这样,在把T类型对象显式隐含转换为S类型,或用 static_cast 显式转换为S类型时,该成员函数会被调用。转换操作符的重载函数不用指 定返回值的类型,这是由于这种情况下重载函数的返回类型与操作符名称一致,因此 c++ 标准规定不能为这类函数指定返回值类型(也不要写 void)

而当对象本身为常数时,为了避免通过指针对数组内容进行修改,只能将对象转换为常指针。

重载指针运算符,作用仅限于把“a”转换成“list”, 对象名a转换成了指向动态数组的指针;

同时,不要以为把对象名a转换成了指向动态数组的指针之后,就能像使用“数组名+下标”一样使用“对象名+下标”来调用数组元素,这样的操作是错误的,编译器是不认的。

参考资料

《C++语言程序设计(第4版)》清华大学出版社 郑莉、董渊、何江舟编著;

百度知道c++类声明中, T& operator[](int i); T operator[](int i_百度知道;

简书https://www.jianshu.com/p/f92a2037d829

最后

以上就是还单身水壶为你收集整理的学习笔记 C++ 动态数组类的声明的全部内容,希望文章能够帮你解决学习笔记 C++ 动态数组类的声明所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部