数组对象运算符重载 [英] Array object operator overloading

查看:55
本文介绍了数组对象运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我是ac / perl程序员,尝试使用C ++。

在我的代码中,我有一个数组类,我在哪里尝试使用+添加两个

数组。

我不知道为什么我总是为结果的第一个元素得到''0'


我的代码(略长,我希望你会忍受一个新手)

--------------------------

使用namespace std;

#include< iostream>

#define MAXARRAYSIZE 500

class MyArr {

public:

int * data,length;


MyArr(){

data = new int [0];

长度= 0;

}


~MyArr(){

if(length) free(data);

}


void newFill(int * d,int l,bool freeD = true){

length = l;

if(freeD)free(data);

data =(int *)malloc(sizeof(int)*(length +2));

for(int i = 0; i< length; i ++)data [i] = d [i];

}


void dispArr(){

for(int i = 0; i< length; i ++)cout<< data [i]<<" \t";

cout<< " \ n";

}


MyArr运算符+(const MyArr& r){

int a [长度];

MyArr ret;

for(int i = 0; i< length; i ++)a [i] = data [i] +(r.data) [i];

ret.newFill(a,length);

return(ret);

}

};


int main(){

MyArr a1,a2;


{

int d [] = {0,1,2,3,4};

int d2 [] = {11,12,13,14,15};

a1.newFill(d,5);

a2.newFill(d2,5);


}


a1.dispArr();

a2.dispArr();


a2 = a1 + a2;

a2.dispArr();

返回(0);

}

--------- -------------结束-------------------


这是输出


0 1 2 3 4

11 12 13 14 15


0 13 15 17 19

------>我希望最后一行的第一个元素= 11


谢谢

Ram




你应该考虑valarray。


class MyArr {
public:
int * data,length;
你至少应该考虑在这里使用向量。
MyArr(){
data = new int [0];
length = 0;
}

~MyArr(){
if(length)free(data);
你在这里泄漏内存。即使你分配int [0],它确实会返回

需要删除的东西。


此外,你的程序有未定义的行为。如果您通过new []

进行分配,则必须使用delete []删除,而不是免费。

删除[]数据。

此外,您做所有这些管理,但你是不可能的。你需要处理

复制构造和复制赋值的情况,对于编译器生成的

这些函数的默认值会做错误的事情。


再次,如果你使用vector< int>而不是错误管理指针,所有这些将由已调试的代码为您处理。 }

void newFill(int * d,int l,bool freeD = true){
length = l;
if(freeD)free(data);
这有什么意义?如果您没有释放数据,它将会丢失。 data =(int *)malloc(sizeof(int)*(length +2));
这里的slop是什么,为什么你现在要转换malloc? for(int i = 0; i< length; i ++)data [i] = d [i];
}
void dispArr(){
for(int i = 0; i< length; i ++)cout<< data [i]<<" \t";
cout<< " \ n";
}

MyArr操作符+(const MyArr& r){


恭喜你最后考虑const,但所有不修改MyArr的函数

也应该被声明为const。

int a [length];


C ++中的数组不能用可变长度声明。

为什么不在ret中使用内部数组呢?

MyArr ret;
for(int i = 0; i< length; i ++)a [i] = data [i] +(r.data)[i];
ret.newFill(a,length) ;
return(ret);




这将返回一个副本,并将调用伪造的(编译器生成的)复制构造函数。


Ron Natalie写道:

Ramprasad A Padmanabhan写道:

你应该考虑valarray。


class MyArr {
public:
int * data,length;



你至少应该考虑在这里使用vector。


MyArr(){
data = new int [0];
length = 0;
}

~MyArr() {
如果(长度)免费(数据);



你在这里泄漏内存。即使你分配int [0],它确实会返回需要删除的东西。

此外,你的程序有未定义的行为。如果你通过new []
进行分配,你必须删除delete [],而不是FREE。
删除[]数据。

此外,你做了所有这些管理,但你是incompelte。你需要
处理复制构造和复制分配的情况,对于
编译器生成的这些函数的默认值会做错事。
<再次,如果你使用vector< int>所有这些都将通过已调试的代码为您处理。

}




void newFill(int * d,int l,bool freeD = true){
length = l;
if(freeD)free(data);



这有什么意义?如果你没有释放数据,它就会丢失。

data =(int *)malloc(sizeof(int)*(length +2));


这里的slop是什么,为什么你现在要切换malloc?

for(int i = 0; i< length; i ++)data [i] = d [i];
}

void dispArr(){
for(int i = 0; i< length; i ++)cout< < data [i]<<" \t";
cout<< " \\\
";
}

MyArr operator +(const MyArr& r){



恭喜你最后考虑const,但所有不修改MyArr的函数也应该声明为const。

int a [length];



C ++中的数组不能用可变长度声明。
为什么不在ret中使用内部数组呢?

MyArr ret;
for(int i = 0; i< length; i ++)a [i] = data [i] +(r.data)[i];
ret.newFill(a,length);
return(ret);



这会返回一个副本并将调用伪造的(编译器生成的)复制
构造函数。



好​​我同意代码看起来很乱(但是,我只是在学习C ++)

我以为我以后应该打扰内存泄漏,所以我放弃了我的

析构函数。

现在我的代码工作正常。那么如何释放分配给的内存

int *数据


谢谢

Ram


" Ramprasad A Padmanabhan" < RA ******************* @ oracle.com>写在

消息新闻:Vq ************* @ news.oracle.com ...

在我的代码下面我有我试图添加两个数组的数组类
使用+ 。
我不知道为什么我总是为结果的第一个元素得到''0'

我的代码(稍长,我希望你能忍受新手)$
请允许我在此过程中发表一些评论... --------------------------
using namespace std ;
#include< iostream>
注意:前2行应该交换编译而不会出错#define MAXARRAYSIZE 500
在C ++中,我们喜欢使用enum {x = 500};或者const int x = 500;

而不是宏,因为这些替代方案将尊重C ++范围。

class MyArr {
public:
int *数据,长度;
(为清楚起见,许多人会更喜欢两个单独的声明。)

MyArr(){
data = new int [0];
length = 0;
虽然分配0大小的数组是合法的,为什么不使用
而是使用NULL指针值呢? }

~MyArr(){
if(length)free(data);
1)基于构造函数,如果length = 0,你将泄漏内存。

但是如果用NULL初始化数据则可以使用

(和你可以省略if(长度)测试。

2)用new []分配的内存必须用delete []释放:

delete [] data;

}

void newFill(int * d,int l,bool freeD = true){
length = l;
if(freeD)free( data);
data =(int *)malloc(sizeof(int)*(length +2));
1)保持一致:在这里使用new int [length]。

2)对于异常/错误安全,它通常是一个很好的

想法在释放之前分配新内存

之前的数据。

3)考虑使用''const'':因为数组指向

来d不被函数修改,最好

将参数声明为:int const * d

for(int i = 0; i< length; i ++) data [i] = d [i];
}

void dispArr(){
for(int i = 0; i< length; i ++)cout<< data [i]<<" \t";
cout<< " \ n";
}

MyArr operator +(const MyArr& r){
int a [length];
这个非常数维数的数组在ISO C ++ 98中是不合法的(虽然它在ISO C'99中已经合法,可能会是

在某些时候也包括在标准C ++中。

为什么不首先为''ret''分配内存,然后

计算它的新内容到位?

MyArr ret;
您可能需要检查(* this)和(r)是否具有

兼容长度! for(int i = 0; i< length; i ++)a [i] = data [i] +(r.data)[i];
ret.newFill(a,length);
返回(ret);
}


你班级的问题在于它没有复制构造函数

(以及赋值运算符):

MyArr(MyArr const& orig);

MyArr& operator =(MyArr const& orig);

这是导致测试代码中出现的错误

的原因。 };




而不是修复你班级中的错误,最好的是

真的是使用std :: vector而不是裸体数组。

这将允许编译器自动正确地生成你需要的额外成员函数:


class MyArr {

public:

std :: vector< int>数据;


MyArr():data(){}

MyArr(int count):data(count){}

>
//默认生成的析构函数和copy-ctr / op都可以

//和以前一样,使用data.size()而不是length:

void dispArr(){

for(int i = 0; i< data.size(); i ++)cout<< data [i]<<" \t";

cout<< " \ n";

}


MyArr运算符+(const MyArr& r)

{

断言(r.data.size()== this-> data.size());

MyArr ret(this.length);

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

ret.data [i] = this-> data [i] + r.data [i] ;

返回ret;

}

};

最后,你写的课看起来非常像

std :: valaray< int>,可在标准C ++库中找到。

另外,您可能还想考虑使用

a模板参数指定数组的大小

(甚至元素类型)......但这是另一个故事。

我希望这会有所帮助,

Ivan

-
http://ivan.vecerina.com/contact/?subject=NG_POST < - 电子邮件联系表格

Brainbench MVP for C ++<> http://www.brainbench.com

Hi All,

I am a c/perl programmer trying my hand at C++.
In my code below I have an array class where I am trying to add two
arrays using "+" .
I am not sure why I get a ''0'' always for the first element of the result

My code ( slightly longish , I hope you would bear with a newbie )
--------------------------
using namespace std;
#include <iostream>
#define MAXARRAYSIZE 500

class MyArr {
public:
int *data,length;

MyArr(){
data = new int[0];
length = 0;
}

~MyArr(){
if(length) free(data);
}

void newFill(int *d,int l,bool freeD = true){
length = l;
if(freeD) free(data);
data = (int*) malloc(sizeof(int)*(length +2));
for(int i=0;i<length;i++) data[i] = d[i];
}

void dispArr() {
for(int i=0;i<length;i++) cout << data[i] <<"\t";
cout << "\n";
}

MyArr operator + ( const MyArr &r){
int a[length];
MyArr ret;
for(int i=0;i<length;i++) a[i]= data[i] + (r.data)[i];
ret.newFill(a,length);
return(ret);
}

};

int main(){
MyArr a1,a2;

{
int d[]={0,1,2,3,4};
int d2[]={11,12,13,14,15};
a1.newFill(d,5);
a2.newFill(d2,5);

}

a1.dispArr();
a2.dispArr();

a2 = a1 + a2;
a2.dispArr();
return(0);
}
---------------------- END -------------------

Here is the output

0 1 2 3 4
11 12 13 14 15

0 13 15 17 19
------> I expect the first element of last row = 11


Thanks
Ram


解决方案

Ramprasad A Padmanabhan wrote:

You should consider valarray.


class MyArr {
public:
int *data,length; You should at least consider using vector here.
MyArr(){
data = new int[0];
length = 0;
}

~MyArr(){
if(length) free(data); You leak memory here. Even when you allocate int[0], it does return
something that needs to be deleted.

Further, your program had undeifned behavior. If you allocate via new[]
you must delete with delete [], not FREE.
delete [] data.
Further, you do all this managment, but you are incompelte. You need to handle
the case of copy construction and copy assignment as well, for the compiler generated
defaults for these functions will do the wrong thing.

Again, if you use vector<int> rather than mismanaging pointers, all this will be
handled for you by already debugged code. }
void newFill(int *d,int l,bool freeD = true){
length = l;
if(freeD) free(data); What is the point of this? If you don''t free the data, it will be lost. data = (int*) malloc(sizeof(int)*(length +2)); What''s with the slop here, and why are you switching ot malloc now? for(int i=0;i<length;i++) data[i] = d[i];
}

void dispArr() {
for(int i=0;i<length;i++) cout << data[i] <<"\t";
cout << "\n";
}

MyArr operator + ( const MyArr &r){
Congratulations on thinking about const finally, but all the functions
that don''t modify MyArr should also be declared const.
int a[length];
Arrays in C++ can not be declared with variable length.
Why not just use the internal array inside ret?
MyArr ret;
for(int i=0;i<length;i++) a[i]= data[i] + (r.data)[i];
ret.newFill(a,length);
return(ret);



This returns a copy and will invoke the bogus (compiler generated) copy constructor.


Ron Natalie wrote:

Ramprasad A Padmanabhan wrote:

You should consider valarray.


class MyArr {
public:
int *data,length;



You should at least consider using vector here.


MyArr(){
data = new int[0];
length = 0;
}

~MyArr(){
if(length) free(data);



You leak memory here. Even when you allocate int[0], it does return
something that needs to be deleted.

Further, your program had undeifned behavior. If you allocate via new[]
you must delete with delete [], not FREE.
delete [] data.
Further, you do all this managment, but you are incompelte. You need
to handle
the case of copy construction and copy assignment as well, for the
compiler generated
defaults for these functions will do the wrong thing.

Again, if you use vector<int> rather than mismanaging pointers, all this
will be
handled for you by already debugged code.

}




void newFill(int *d,int l,bool freeD = true){
length = l;
if(freeD) free(data);



What is the point of this? If you don''t free the data, it will be lost.

data = (int*) malloc(sizeof(int)*(length +2));



What''s with the slop here, and why are you switching ot malloc now?

for(int i=0;i<length;i++) data[i] = d[i];
}

void dispArr() {
for(int i=0;i<length;i++) cout << data[i] <<"\t";
cout << "\n";
}

MyArr operator + ( const MyArr &r){


Congratulations on thinking about const finally, but all the functions
that don''t modify MyArr should also be declared const.

int a[length];


Arrays in C++ can not be declared with variable length.
Why not just use the internal array inside ret?

MyArr ret;
for(int i=0;i<length;i++) a[i]= data[i] + (r.data)[i];
ret.newFill(a,length);
return(ret);


This returns a copy and will invoke the bogus (compiler generated) copy
constructor.


Ok I agree the code looks messy ( but hey I am just learning C++)
I thought I should bother about memory leak later , So I dropped my
destructor.
Now my code is working fine. So how do I free the memory allocated to
int *data

Thanks
Ram


"Ramprasad A Padmanabhan" <ra*******************@oracle.com> wrote in
message news:Vq*************@news.oracle.com...

In my code below I have an array class where I am trying to add two arrays
using "+" .
I am not sure why I get a ''0'' always for the first element of the result

My code ( slightly longish , I hope you would bear with a newbie ) Hi, allow me to make some comments along the way... --------------------------
using namespace std;
#include <iostream> NB: the 2 previous lines should be swapped to compile without error #define MAXARRAYSIZE 500 In C++, we like to use enum { x = 500 }; or const int x = 500;
instead of macros, as these alternatives will respect C++ scopes.
class MyArr {
public:
int *data,length; (Many will prefer two separate declarations for clarity.)
MyArr(){
data = new int[0];
length = 0; While it is legal to allocate a 0-size array, why not
use a NULL pointer value instead? }

~MyArr(){
if(length) free(data); 1) Based on the constructor, you will leak memory if length=0.
But it will be ok if you initialize data with NULL instead
(and you can omit the if(length) test anyway).
2) Memory allocated with new[] must be freed with delete[] :
delete[] data;
}

void newFill(int *d,int l,bool freeD = true){
length = l;
if(freeD) free(data);
data = (int*) malloc(sizeof(int)*(length +2)); 1) be consistent: use new int[length] here as well.
2) For exception/error safety, it is usually a good
idea to allocate the new memory before freeing
the previous data.
3) Consider using ''const'': because the array pointed
to by d is not modified by the function, best
would be to declare the parameter as: int const* d
for(int i=0;i<length;i++) data[i] = d[i];
}

void dispArr() {
for(int i=0;i<length;i++) cout << data[i] <<"\t";
cout << "\n";
}

MyArr operator + ( const MyArr &r){
int a[length]; This array of a non-const dimention is not legal in ISO C++ 98
(although its has become legal in ISO C''99, and probably will
at some point be included in standard C++ as well).
Why not first allocate the memory for ''ret'', and then
compute its new contents in place ?
MyArr ret; You probably need to check that (*this) and (r) have
compatible lengths ! for(int i=0;i<length;i++) a[i]= data[i] + (r.data)[i];
ret.newFill(a,length);
return(ret);
}
The problem with your class is that it lacks a copy-constructor
(and an assignment operator):
MyArr( MyArr const& orig );
MyArr& operator=( MyArr const& orig );
This is what causes the error
you observe in your test code. };



Rather than fixing the errors in your class, the best would
really be to use std::vector instead of a naked array.
This will allow the compiler to automatically and correctly
generate the additional member functions you need:

class MyArr {
public:
std::vector<int> data;

MyArr() : data () {}
MyArr(int count) : data(count) {}

// the default-generated destructor and copy-ctr/op are ok
// same as before, uses data.size() instead of length :
void dispArr() {
for(int i=0;i<data.size();i++) cout << data[i] <<"\t";
cout << "\n";
}

MyArr operator + ( const MyArr &r)
{
assert( r.data.size() == this->data.size() );
MyArr ret(this.length);
for(int i=0;i<data.size();++i)
ret.data[i] = this->data[i] + r.data[i];
return ret;
}
};
Finally, the class you are writing looks very much like
std::valaray<int>, available in the standard C++ library.
Alternatively, you may also want to consider using
a template parameter to specify the size of the array
(and even the element type)... but that''s another story.
I hope this helps,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <> http://www.brainbench.com


这篇关于数组对象运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆