CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

如何复制元素为const类型的数组?

楼主hai_feng(海风)2005-05-29 21:26:53 在 C/C++ / C++ 语言 提问

我做一个数组模板类,构造方式需要原封不动复制c++系统数组,但是当数组元素为const类型时却出现了operator   =()调用时的左值问题,如何解决这个问题?请高手指教。下面是我的代码例子:  
   
  template<typename   TElementType>class   CArray   //数组类  
  {  
  public:  
  CArray(TElementType   *   aElement,   LONG   nSize);  
   
  protected:  
  TElementType   *   m_aElement;  
  LONG   m_nSize;  
  };  
   
  template<typename   TElementType>   CArray<   TElementType   >::CArray(TElementType   *   aElement,   LONG   nSize)   //复制C++系统数组的构造函数  
  {  
  if(aElement   ==   NULL)  
  {  
  m_aElement   =   NULL;  
  m_nSize   =   0;  
  }  
  else  
  {  
  m_aElement   =   new   TElementType[   nSize   ];  
  for(int   i=0;   i<nSize;   i++)  
  m_aElement[   i   ]   =   aElement[   i   ];   //这里编译出错,由于模板实例化时传入的是CArray<const   int>类型,operator   =()操作无法执行,如何构造、复制元素为const类型的数组成为很大的问题。  
  }  
  } 问题点数:100、回复次数:18Top

1 楼qhfu(改个名字)回复于 2005-05-29 21:39:36 得分 1

基本上是无解,     const变量只能在初始化列表中初始化。在这里赋值已经做了第二次了,所以   重复对const对象赋值。Top

2 楼sinkinglife(沉沦)回复于 2005-05-29 21:44:13 得分 1

不好办,没有想到好办法!  
   
  Top

3 楼defyer007(深入浅出)回复于 2005-05-30 02:06:01 得分 5

template<typename   TElementType>   CArray<   TElementType   >::CArray(TElementType   *   aElement,   LONG   nSize):m_aElement=aElement   //复制C++系统数组的构造函数  
  {  
  if(aElement   ==   NULL)  
  {  
  //m_aElement   =   NULL;  
  m_nSize   =   0;  
  }  
  或者将m_aElement设为指向指针的指针:  
  TElementType   **m_aElemnet;  
  再指向aElemnet  
  不知道行不行Top

4 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-05-30 07:47:54 得分 2

个人意见:  
   
  把数组声明为static   const  
   
  这样就不用复制了Top

5 楼majcos(千里之行,始于足下)回复于 2005-05-30 09:06:14 得分 76

使用定位new操作符,在VC++2005上可以实现。程序如下(增加了一个构造函数)  
  #include   <iostream>  
  using   namespace   std;  
   
  template<class   TElementType>  
  class   CArray   //数组类  
  {  
  public:  
  CArray(TElementType*   aElement,   long   nSize);  
  CArray(TElementType*   aElement,   long   nSize,   int   typeSize);  
  public:  
  TElementType*   m_aElement;  
  long   m_nSize;  
  };  
   
  template<typename   TElementType>    
  CArray<   TElementType   >::CArray(TElementType   *   aElement,   long   nSize)   //复制C++系统数组的构造函数  
  {  
  if(aElement   ==   NULL)  
  {  
  m_aElement   =   NULL;  
  m_nSize   =   0;  
  }  
  else  
  {  
  m_aElement   =   new   TElementType[   nSize   ];  
  for(int   i=0;   i<nSize;   i++)  
  m_aElement[   i   ]   =   aElement[   i   ];   //这里编译出错,由于模板实例化时传入的是CArray<const   int>类型,operator   =()操作无法执行,如何构造、复制元素为const类型的数组成为很大的问题。  
  }  
  }  
   
  template<typename   TElementType>    
  CArray<   TElementType   >::CArray(TElementType*   aElement,   long   nSize,   int   typeSize)  
  {  
  if(aElement   ==   NULL)  
  {  
  m_aElement   =   NULL;  
  m_nSize   =   0;  
  }  
  else  
  {  
  char*   p   =   new   char[nSize*typeSize];  
  memcpy(p,aElement,nSize*typeSize);  
  m_aElement   =   new   (p)   TElementType[   nSize   ];//使用定位new    
  }  
  }  
   
   
  void   main(){  
  int   x[100];  
  for(int   i=0;   i<100;   i++)  
  x[i]   =   i;  
  CArray<const   int>   a(x,100,sizeof(const   int));  
  for(int   i=0;   i<100;   i++)  
  cout<<a.m_aElement[i]<<"   "<<endl;  
  system("pause");  
  }Top

6 楼majcos(千里之行,始于足下)回复于 2005-05-30 09:13:53 得分 1

不知道在其他编译器上能编译通过不,C++primer上有这样一段话:  
          我们不能在空闲存储区内创建内置类型元素的const   数组一个简单的原因是我们不  
  能初始化用new   表达式创建的内置类型数组的元素所有在空闲存储区内被创建的const   对  
  象都必须被初始化而且因为const   数组不能被初始化除了类数组所以试图用new  
  表达式创建一个内置类型的const   数组会导致编译错误  
  const   int   *pci   =   new   const   int[100];   //   错误  
   
  但是这条语句在VC2005上是没有编译错误的,所以我上面的程序能够正常运行。Top

7 楼darkstar21cn(≮天残≯无畏)(死亡进行时)回复于 2005-05-30 09:39:44 得分 5

把CArray(TElementType   *   aElement,   long   nSize)   改成CArray(TElementType   const*   aElement,   long   nSize)Top

8 楼stkane(左手无名指)回复于 2005-05-30 10:04:42 得分 5

我偷偷地告诉你一个operator一定管用,你要给我满分哦  
  答案是const_cast,你可能需要启用RTTI来鉴别什么时候需要用这个转换。详细的资料建议你查查C++   Primer   3rd   editionTop

9 楼lonelyforest(一生所爱)回复于 2005-05-30 10:25:02 得分 1

同意楼上的观点,必要是就用显式转换了!Top

10 楼guyaguya(我只愿面朝大海,春暖花开)回复于 2005-05-30 11:11:46 得分 1

声明为const就是不想对成员进行修改  
  想要修改就不要声明为const了吧Top

11 楼hai_feng(海风)回复于 2005-05-30 13:05:04 得分 0

to   stkane(左手无名指)  
  我偷偷地告诉你一个operator一定管用,你要给我满分哦  
  答案是const_cast,你可能需要启用RTTI来鉴别什么时候需要用这个转换。详细的资料建议你查查C++   Primer   3rd   edition  
   
  ---------------------  
  好像还是不行:  
  CArray<   TElementType   >::CArray(TElementType   *   aElement,   long   nSize)   //复制C++系统数组的构造函数  
  {  
  if(aElement   ==   NULL)  
  {  
  m_aElement   =   NULL;  
  m_nSize   =   0;  
  }  
  else  
  {  
  m_aElement   =   new   TElementType[   nSize   ];  
  for(int   i=0;   i<nSize;   i++)  
  const_cast<TElementType   *>(   m_aElement   )[   i   ]   =   aElement[   i   ];   //同样是编译出错,我猜const_cast是对指针或引用抛去const,但不是对类型抛去const,所以还是要明确写出类型的,而TElementType这个在模板中复合了的类型就无法拆分了。  
  }  
  }Top

12 楼hai_feng(海风)回复于 2005-05-30 13:09:41 得分 0

to     majcos(千里之行,始于足下)    
  你使用的是直接内存复制的办法,这个我也想到过,但是现在用的是c++而不是c,如果在c语言你的是很好的办法,但c++语言多了个在内存空间上的构造函数,你这样就没有为每个数组元素调用构造函数了,在c++是错误的。Top

13 楼hai_feng(海风)回复于 2005-05-30 13:21:19 得分 0

darkstar21cn(爱上小猫的小狗)(读不懂爱情所以来读程序)    
  把CArray(TElementType   *   aElement,   long   nSize)   改成CArray(TElementType   const*   aElement,   long   nSize)  
   
  不行!无论把const放在那个位置都试过都不行,这样充其量只是为指针加多一个const修饰,你不是要我利用编译器可能潜在的bug吧?Top

14 楼mostideal(三甲)回复于 2005-05-30 13:33:29 得分 1

这问题好像很难,我暂时是想不出办法。等高手来继续。。Top

15 楼hai_feng(海风)回复于 2005-05-30 14:00:24 得分 0

to   majcos(千里之行,始于足下)    
  你在同一个位置   char*   p   new了2次,那么应该调用多少次delete?Top

16 楼hai_feng(海风)回复于 2005-05-30 14:03:59 得分 0

我已经想到办法了,多谢majcos(千里之行,始于足下)的启发,只要逐一对每个数组元素使用定位new即可,new时可以调用构造函数用于复制,但是具体代码我还没有写出来,如果有人比我更快贴出来,分数当然最高了。Top

17 楼hai_feng(海风)回复于 2005-05-30 14:05:08 得分 0

只要逐一对每个数组元素使用定位new即可,new时可以调用构造函数用于复制  
  -------  
  但这样怎么调用delete呢?是否可以一次过delete?Top

18 楼whyglinux(山青水秀)回复于 2005-05-30 14:24:50 得分 1

>>   当数组元素为const类型时却出现了operator   =()调用时的左值问题,如何解决这个问题?  
   
  一个简单的解决方法是要求你在定义对象的时候要把元素类型设置为int(   CArray<int>),而不是const   int(   CArray<const   int>)。注意:在定义模板类对象的时候模板参数是由用户指定的,而不是由编译器推导出来的。  
   
  但是,这样的话你的程序要做出必要的调整:  
   
  一是不要把初始化使用的数组的类型和CArray的元素的类型进行关联,即用来初始化的数组类型可以和CArray的元素的类型不一致,只要存在着默认的类型转换。  
   
  二是为了可以使用const数组进行初始化,在构造函数中应该使用   const   指针。  
   
  即对构造函数修改如下:  
   
  template<class   TElementType>  
  class   CArray  
  {  
  public:  
  //CArray(TElementType*   aElement,   long   nSize);  
  template<typename   TInitArrayType>  
  CArray(const   TInitArrayType*   aElement,   long   nSize);  
  //   ...Top

相关问题

  • 数组的复制
  • 数组复制的问题?
  • 数组元素的调用
  • 应如何定义一个数组 其中数组元素又是数组?
  • 一个字符数组复制到另一个字符数组?
  • 关于数组复制的问题
  • 字符数组复制的问题
  • 数组元素怎么取出来?
  • 怎么得到数组的元素数?
  • 如何使用元素数组?

关键词

  • c++
  • 函数
  • 指针
  • 模板
  • template
  • 系统
  • 解决
  • aelement
  • telementtype
  • 数组

得分解答快速导航

  • 帖主:hai_feng
  • qhfu
  • sinkinglife
  • defyer007
  • useresu
  • majcos
  • majcos
  • darkstar21cn
  • stkane
  • lonelyforest
  • guyaguya
  • mostideal
  • whyglinux

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo