C++运算符重载 - “重新创建 Vector”
我目前正在学习拼贴二级编程课程...我们正在研究运算符重载...为此,我们将重建向量类... 我正在构建该类,发现它的大部分都是基于 [] 运算符
。当我尝试实现 + 运算符时,我遇到了一个奇怪的错误,这是我的教授以前从未见过的(显然是因为课程将 IDE 从 MinGW 切换到 VS Express...)(我正在使用 Visual Studio Express 2008 C++ 版...)
Vector.h
#include <string>
#include <iostream>
using namespace std;
#ifndef _VECTOR_H
#define _VECTOR_H
const int DEFAULT_VECTOR_SIZE = 5;
class Vector
{
private:
int * data;
int size;
int comp;
public:
inline Vector (int Comp = 5,int Size = 0)
: comp(Comp), size(Size) { if (comp > 0) { data = new int [comp]; }
else { data = new int [DEFAULT_VECTOR_SIZE];
comp = DEFAULT_VECTOR_SIZE; }
}
int size_ () const { return size; }
int comp_ () const { return comp; }
bool push_back (int);
bool push_front (int);
void expand ();
void expand (int);
void clear ();
const string at (int);
int& operator[ ](int);
int& operator[ ](int) const;
Vector& operator+ (Vector&);
Vector& operator- (const Vector&);
bool operator== (const Vector&);
bool operator!= (const Vector&);
~Vector() { delete [] data; }
};
ostream& operator<< (ostream&, const Vector&);
#endif
Vector.cpp
#include <iostream>
#include <string>
#include "Vector.h"
using namespace std;
const string Vector::at(int i) {
this[i];
}
void Vector::expand() {
expand(size);
}
void Vector::expand(int n ) {
int * newdata = new int [comp * 2];
if (*data != NULL) {
for (int i = 0; i <= (comp); i++) {
newdata[i] = data[i];
}
newdata -= comp;
comp += n;
data = newdata;
delete newdata;
}
else if ( *data == NULL || comp == 0) {
data = new int [DEFAULT_VECTOR_SIZE];
comp = DEFAULT_VECTOR_SIZE;
size = 0;
}
}
bool Vector::push_back(int n) {
if (comp = 0) { expand(); }
for (int k = 0; k != 2; k++) {
if ( size != comp ){
data[size] = n;
size++;
return true;
}
else {
expand();
}
}
return false;
}
void Vector::clear() {
delete [] data;
comp = 0;
size = 0;
}
int& Vector::operator[] (int place) { return (data[place]); }
int& Vector::operator[] (int place) const { return (data[place]); }
Vector& Vector::operator+ (Vector& n) {
int temp_int = 0;
if (size > n.size_() || size == n.size_()) { temp_int = size; }
else if (size < n.size_()) { temp_int = n.size_(); }
Vector newone(temp_int);
int temp_2_int = 0;
for ( int j = 0; j <= temp_int &&
j <= n.size_() &&
j <= size;
j++) {
temp_2_int = n[j] + data[j];
newone[j] = temp_2_int;
}
////////////////////////////////////////////////////////////
return newone;
////////////////////////////////////////////////////////////
}
ostream& operator<< (ostream& out, const Vector& n) {
for (int i = 0; i <= n.size_(); i++) {
////////////////////////////////////////////////////////////
out << n[i] << " ";
////////////////////////////////////////////////////////////
}
return out;
}
错误:
out << n[i] << " "; error C2678:
二进制“[”:找不到哪个运算符 接受类型的左操作数 'const Vector'(或者没有 可接受的转换)
return newone;
错误 C2106: '=' : left 操作数必须是左值
如上所述,我是一名学生,正在选择计算机科学作为我选择的专业,我希望得到提示、指示和更好的方法:D
I am currently in a collage second level programing course... We are working on operator overloading... to do this we are to rebuild the vector class...
I was building the class and found that most of it is based on the [] operator
. When I was trying to implement the + operator
I run into a weird error that my professor has not seen before (apparently since the class switched IDE's from MinGW to VS express...) (I am using Visual Studio Express 2008 C++ edition...)
Vector.h
#include <string>
#include <iostream>
using namespace std;
#ifndef _VECTOR_H
#define _VECTOR_H
const int DEFAULT_VECTOR_SIZE = 5;
class Vector
{
private:
int * data;
int size;
int comp;
public:
inline Vector (int Comp = 5,int Size = 0)
: comp(Comp), size(Size) { if (comp > 0) { data = new int [comp]; }
else { data = new int [DEFAULT_VECTOR_SIZE];
comp = DEFAULT_VECTOR_SIZE; }
}
int size_ () const { return size; }
int comp_ () const { return comp; }
bool push_back (int);
bool push_front (int);
void expand ();
void expand (int);
void clear ();
const string at (int);
int& operator[ ](int);
int& operator[ ](int) const;
Vector& operator+ (Vector&);
Vector& operator- (const Vector&);
bool operator== (const Vector&);
bool operator!= (const Vector&);
~Vector() { delete [] data; }
};
ostream& operator<< (ostream&, const Vector&);
#endif
Vector.cpp
#include <iostream>
#include <string>
#include "Vector.h"
using namespace std;
const string Vector::at(int i) {
this[i];
}
void Vector::expand() {
expand(size);
}
void Vector::expand(int n ) {
int * newdata = new int [comp * 2];
if (*data != NULL) {
for (int i = 0; i <= (comp); i++) {
newdata[i] = data[i];
}
newdata -= comp;
comp += n;
data = newdata;
delete newdata;
}
else if ( *data == NULL || comp == 0) {
data = new int [DEFAULT_VECTOR_SIZE];
comp = DEFAULT_VECTOR_SIZE;
size = 0;
}
}
bool Vector::push_back(int n) {
if (comp = 0) { expand(); }
for (int k = 0; k != 2; k++) {
if ( size != comp ){
data[size] = n;
size++;
return true;
}
else {
expand();
}
}
return false;
}
void Vector::clear() {
delete [] data;
comp = 0;
size = 0;
}
int& Vector::operator[] (int place) { return (data[place]); }
int& Vector::operator[] (int place) const { return (data[place]); }
Vector& Vector::operator+ (Vector& n) {
int temp_int = 0;
if (size > n.size_() || size == n.size_()) { temp_int = size; }
else if (size < n.size_()) { temp_int = n.size_(); }
Vector newone(temp_int);
int temp_2_int = 0;
for ( int j = 0; j <= temp_int &&
j <= n.size_() &&
j <= size;
j++) {
temp_2_int = n[j] + data[j];
newone[j] = temp_2_int;
}
////////////////////////////////////////////////////////////
return newone;
////////////////////////////////////////////////////////////
}
ostream& operator<< (ostream& out, const Vector& n) {
for (int i = 0; i <= n.size_(); i++) {
////////////////////////////////////////////////////////////
out << n[i] << " ";
////////////////////////////////////////////////////////////
}
return out;
}
Errors:
out << n[i] << " "; error C2678:
binary '[' : no operator found which
takes a left-hand operand of type
'const Vector' (or there is no
acceptable conversion)
return newone;
error C2106: '=' : left
operand must be l-value
As stated above, I am a student going into Computer Science as my selected major I would appreciate tips, pointers, and better ways to do stuff :D
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
this:
是一个非常量成员函数。这意味着不能在
const Vector
上调用它。通常,下标运算符的实现方式是返回一个引用(如果您返回一个值,就像您所做的那样,则不能将其用作左值,例如您不能执行 newone[j] = temp_2_int ; 就像您在代码中一样):
为了能够在 const 对象上调用它,您还应该提供成员函数的 const 版本:
既然您要求“提示、指针和更好的方法做一些事情:”
_VECTOR_H
。以下划线开头,后跟大写字母的名称保留用于实现。 很多关于下划线的规则。using namespace std
。operator+
应该采用const Vector&
因为它不会修改其参数。at
应该返回一个int
并且应该匹配 C++ 标准库容器的语义(即,如果i
超出,它应该抛出异常您需要使用(*this)[i]
来调用重载的operator[]
*
的内容 。在一些地方,您混淆了指针和它们指向的对象,=
和==
(例如,在if (comp. 编译器将对此发出警告。
data
永远不会出现,那么 无效的。This:
is a non-const member function. It means that it cannot be called on a
const Vector
.Usually, the subscript operator is implemented such that it returns a reference (if you return a value, like you are doing, you can't use it as an lvalue, e.g. you can't do
newone[j] = temp_2_int;
like you have in your code):In order to be able to call it on a const object, you should also provide a const version of the member function:
Since you ask for "tips, pointers, and better ways to do stuff:"
_VECTOR_H
. Names beginning with an underscore followed by a capital letter are reserved for the implementation. There are a lot of rules about underscores.using namespace std
in a header.operator+
should take aconst Vector&
since it is not going to modify its argument.at
should return anint
and should match the semantics of the C++ standard library containers (i.e., it should throw an exception ifi
is out of bounds. You need to use(*this)[i]
to call your overloadedoperator[]
.*
operator does. In several places you've confused pointers and the objects to which they point.=
with==
(e.g. inif (comp = 0)
). The compiler will warn you about this. Don't ignore warnings.data
is never NULL.无法将其纳入对尼尔答案的评论中,所以我必须在这里详细说明。
关于您的
expand()
函数。看起来这个函数的工作是通过n
个元素扩展具有comp
元素的内部存储,同时保持 Vector 的size
。那么让我们来看看您拥有的内容。好的,您刚刚创建了一个新数组,其大小是旧数组的两倍。错误:为什么新的尺寸与
n
没有任何关系?错误:
*data
是数组中的第一个int
元素。它不是一个指针。为什么将其与NULL
进行比较?概念错误:即使您说
if (data != NULL)
,这可能是一个测试,看看是否存在数组,但data 在什么时间点
曾经设置为NULL
吗?如果内存不足,new []
不会返回NULL
;它抛出异常。警告:您正在复制整个数组,但只有前
size
元素有效。循环可以运行到size
就可以了。错误:指针数学错误。
newdata
设置为一个指针,指向谁知道 (comp
int
从newdata
的开头返回的位置?! ),而且几乎可以肯定的是,如果给delete []
一个指针,它会破坏内存。这很好,就其本身而言。
错误:您存储了一个指针,然后立即删除了它的内存,使其成为无效指针。
错误:这应该在您的构造函数中,而不是在这里。同样,没有任何东西将
data
设置为NULL
,并且*data
是一个int
,而不是指针。这个函数应该做什么:
comp + n
元素组成的新数组size
元素从旧数组复制到新数组,data
指向新数组祝你好运。
Can't fit this into a comment on Neil's answer, so I'm gonna have to go into more detail here.
Regarding your
expand()
function. It looks like this function's job is to expand the internal storage, which hascomp
elements, byn
elements, while maintaining thesize
of the Vector. So let's walk through what you have.Okay, you just created a new array that is twice as big as the old one. Error: Why doesn't the new size have anything to do with
n
?Error:
*data
is the firstint
element in your array. It's not a pointer. Why is it being compared toNULL
?Concept Error: Even if you said
if (data != NULL)
, which could be a test to see if there is an array at all, at what point in time isdata
ever set toNULL
?new []
doesn't returnNULL
if it's out of memory; it throws an exception.Warning: You're copying the whole array, but only the first
size
elements are valid. The loop could just run up tosize
and you'd be fine.Error: Bad pointer math.
newdata
is set to a pointer to who knows where (comp
int
s back from the start ofnewdata
?!), and almost certainly a pointer that will corrupt memory if given todelete []
.This is fine, for what it is.
Error: You stored a pointer and then immediately deleted its memory, making it an invalid pointer.
Error: This should be in your constructor, not here. Again, nothing ever sets
data
toNULL
, and*data
is anint
, not a pointer.What this function should do:
comp + n
elementssize
elements from the old array to the new onedata
to point to the new arrayGood luck.
除了其他人已经写过的关于您的
operator[]()
的内容之外:您的
operator+()
采用每个非const
引用的右侧——就好像它会试图改变它一样。然而,对于A+B
,每个人都希望B
保持不变。此外,我将实现所有二元运算符,将其操作数同等对待(即,不更改其中任何一个)作为非成员函数。作为成员函数,左侧 (
this
) 可以进行不同的处理。 (例如,它可能会受到派生类中的覆盖版本的影响。)然后,IME 将
operator+()
基于operator+=()
总是好的。operator+=()
不会平等地对待其操作数(它会更改其左边的操作数),因此最好将其作为成员函数来完成。完成此操作后,在其之上实现operator+()
就是小菜一碟了。最后,operator+() 永远不应该返回对对象的引用。当您说
A+B
时,您希望返回一个新对象,而不是更改某些现有对象并返回对该对象的引用。Besides of what others already wrote about your
operator[]()
:Your
operator+()
takes the right-hand side per non-const
reference - as if it would attempt to change it. However, withA+B
everyone would expectB
to remain unchanged.Further, I would implement all binary operators treating their operands equally (i.e., not changing either of them) as non-member functions. As member functions the left-hand side (
this
) could be treated differently. (For example, it could be subjected to overwritten versions in derived classes.)Then, IME it's always good to base
operator+()
onoperator+=()
.operator+=()
does not treat its operands equally (it changes its left one), so it's best done as a member function. Once this is done, implementingoperator+()
on top of it is a piece of cake.Finally,
operator+()
should never, never ever return a reference to an object. When you sayA+B
you expect this to return a new object, not to change some existing object and return a reference to that.您的代码中有太多错误,以至于很难知道从哪里开始。其一:
删除一个指针,然后立即取消引用它。
并且:(
我认为)这是一个整数向量。为什么这会返回一个字符串?对此应用 [] 运算符不会调用您的运算符 [] 重载 - 它将其视为数组,但事实并非如此。
There are so many errors in your code that it is hard to know where to start. Here's one:
You delete a pointer and then immediately dereference it.
And:
This is (I think) a vector of ints. why is this returning a string? And applying the [] operator to this does not call your operator[] overload - it treats this as an array, which it isn't.
您需要提供两个版本的运算符[]。对于访问:
对于写入元素:
在上述两个例子中,将 T 替换为元素的类型。出现此问题的原因是,只有标记为“const”的函数才能在声明为“const”的对象上调用。将所有非变异函数标记为“const”绝对是您应该做的事情,称为“const 正确性”。由于返回对元素的引用(写入所必需的)允许底层对象发生变化,因此该版本的函数不能设为“const”。因此,需要一个只读的“const”重载。
您可能还有兴趣阅读:
You need to provide two versions of your operator[]. For accessing:
For writing to the element:
In both of the above, replace T with the type of the elements. The reason you have this problem is that only functions that are marked "const" may be invoked on an object declared to be "const". Marking all non-mutating functions as "const" is definitely something you should do and is called "const-correctness". Since returning a reference to an element (necessary for writing) allows the underlying object to be mutated, that version of the function cannot be made "const". Therefore, a read-only "const" overload is needed.
You may also be interested in reading:
这样
您就可以对 const 向量执行
[]
操作。函数声明后的const
表示类实例 (this
) 被视为const Vector
,这意味着您将无法修改正常属性。或者换句话说:仅具有对属性的读取访问权限的方法。This should be
so that you will be able to do the
[]
operation on const vectors. Theconst
after the function declaration means that the class instance (this
) is treated asconst Vector
, meaning you won't be able to modify normal attributes. Or in other words: A method that only has read access to attributes.