gpt4 book ai didi

c++ - 重载 << 运算符返回错误值 (C++)

转载 作者:行者123 更新时间:2023-11-30 02:33:28 25 4
gpt4 key购买 nike

我是 C++ 的初学者,最近在我练习运算符重载和模板的小程序中遇到了一个非常令人沮丧的问题。

我创建了一个名为 SortedVector 的模板类,它可以存储各种类型的实例。

using namespace std;

template <class T, int size> class SortedVector {
public:
SortedVector();
bool add(const T& v);
T& median();
void sortArray();
void removeLarge(const T& v);
void print(ostream &os);
void compexch(T& x, T& y);
void sortArray(T* data, int s);

private:
T arr[size];
int arraySize;
};

template <class T, int size> SortedVector<T, size>::SortedVector() {


arraySize = 0;

for (int i = 0; i < size; i++) {
arr[i] = T();
}
}

template <class T, int size> bool SortedVector<T, size>::add(const T& v) {

if (arraySize > size - 1) {
cout << "Array is full!" << endl;
return false;
} else {

arr[arraySize] = v;
arraySize++;

sortArray(arr, arraySize);
}

return true;
}

template <class T, int size> void SortedVector<T, size>::sortArray(T* data, int s) {
for (int i = 0; i < s - 1; i++) {
for (int j = i + 1; j < s; j++) {
compexch(data[i], data[j]);
}
}
}

template <class T, int size > T & SortedVector<T, size>::median() {

}

template <class T, int size> void SortedVector<T, size>::removeLarge(const T & v) {

}

template <class T, int size> void SortedVector<T, size>::print(ostream & os) {


for (int i = 0; i < arraySize; i++) {
cout << arr[i] << endl;
}
}

template <class T, int size> inline void SortedVector<T, size>::compexch(T& x, T& y) {
if (y < x) {
T temp = x;
x = y;
y = temp;
}
}

它可以成功存储整数,也可以存储多边形(在之前的作业中创建的自定义类)。

多边形.h:

class Polygon {
public:

Polygon(Vertex vertexArray[], int size);
Polygon() : vertices(0), arraySize(0) {}
~Polygon() {delete[] vertices;}
void add(Vertex v);
float area();
int minx();
int maxx();
int miny();
int maxy();
int numVertices() const {return arraySize;}
friend ostream &operator << (ostream &output, const Polygon& polygon);
friend bool operator > (Polygon polygon1, Polygon polygon2);
friend bool operator < (Polygon polygon1, Polygon polygon2);

private:

int arraySize;
Vertex * vertices;

};

Polygon.cpp 声明:

using namespace std;

void Polygon::add(Vertex v) {
arraySize++;
Vertex * tempVertexes = new Vertex[arraySize];
for (int i = 0; i < arraySize; i++) {
if (i == arraySize - 1) {
tempVertexes[i] = v;
} else {
tempVertexes[i] = vertices[i];
}
}
delete [] vertices;
vertices = tempVertexes;

}

Polygon::Polygon(Vertex vertexArray[], int size) {
arraySize = size;
vertices = new Vertex[size];

for (int i = 0; i < size; i++) {
vertices[i] = vertexArray[i];
}
}

float Polygon::area() {
float area = 0.0f;

for (int i = 0; i < arraySize - 1; ++i) {
area += (vertices[i].getXposition() * vertices[i + 1].getYposition()) - (vertices[i + 1].getXposition() * vertices[i].getYposition());
}

area += (vertices[0].getYposition() * vertices[arraySize - 1].getXposition()) - (vertices[arraySize - 1].getYposition() * vertices[0].getXposition());

area = abs(area) *0.5;

return area;
}



ostream& operator<<(ostream &output, const Polygon& polygon) { //Kolla denna!


output << "{";
for (int i = 0; i < polygon.numVertices(); i++) {
output << "(" << polygon.vertices[i].getXposition() << "," << polygon.vertices[i].getYposition() << ")";

}
output << "}";

return output;

}

bool operator>(Polygon polygon1, Polygon polygon2) {
if (polygon1.area() > polygon2.area()) {
return true;
} else {
return false;
}
}

bool operator<(Polygon polygon1, Polygon polygon2) {
if (polygon1.area() < polygon2.area()) {
return true;
} else {
return false;
}
}


template <class T> inline void compexch(T& x, T& y) {
if (y < x) {
T temp = x;
x = y;
y = temp;
}
}

顶点类的代码:

class Vertex {
public:
Vertex() : y(0), x(0) {}
Vertex(int xPosition, int yPosition) : x(xPosition), y(yPosition) {}
~Vertex() {}
int getXposition() const {return x;}
int getYposition() const {return y;}

private:
int x;
int y;


};

然而,问题是重载的 <<-operator 似乎从 main-method 打印出错误的值:

int main() {

SortedVector<Polygon, 10> polygons;
SortedVector<int, 6> ints;

ints.add(3);
ints.add(1);
ints.add(6);

Vertex varr[10];
varr[0] = Vertex(0, 0);
varr[1] = Vertex(10, 0);
varr[2] = Vertex(5, 2);
varr[3] = Vertex(5, 5);
polygons.add(Polygon(varr, 4));
cout << "varr area:" << (Polygon(varr, 4)).area() << endl;

varr[0] = Vertex(0, 0);
varr[1] = Vertex(25, 8);
varr[2] = Vertex(10, 23);
polygons.add(Polygon(varr, 3));
cout << "var area (1):" << (Polygon(varr, 3)).area() << endl;
varr[0] = Vertex(0, 0);
varr[1] = Vertex(5, 0);
varr[2] = Vertex(5, 3);
varr[3] = Vertex(4, 8);
varr[4] = Vertex(2, 10);
polygons.add(Polygon(varr, 5));
cout << "var area (2):" << (Polygon(varr, 5)).area() << endl;
polygons.print(cout);
ints.print(cout);

cout << "MEDIAN: " << ints.median() << endl;
cout << "MEDIAN: " << polygons.median() << endl;

return 0;

}

打印出来的代码是:

var area (1):247.5
var area (2):33.5
{(6029504,0)(5,0)(5,3)}
{(6029504,0)(5,0)(5,3)(4,8)}
{(6029504,0)(5,0)(5,3)(4,8)(2,10)}
1
3
6
MEDIAN: 1
MEDIAN: {(6029504,0)(5,0)(5,3)}

首先,该方法打印出相同但大小不同的多边形。其次,它为数组中的第一个对象指出了错误的 getXPosition()。其他所有内容(已实现,如整数和区域)都是正确的。为什么是这样?我是否遗漏了一些重要的东西,或者我是否完全不喜欢我的程序?

如果需要更多代码,我很乐意提供。

问候

最佳答案

鉴于您发布的代码,问题很清楚。

您正在通过 Polygon在这里按值(value)计算:

friend bool operator > (Polygon polygon1, Polygon polygon2);
friend bool operator < (Polygon polygon1, Polygon polygon2);

并且您正在此处复制和分配值:compexch :

if (y < x) {
T temp = x; // copy constructor
x = y; // assignment
y = temp; // assigment
}

这意味着将进行复制,并且无法安全地复制您的 Polygon 类。调用这些函数中的任何一个时都会出现内存泄漏和错误。

您应该实现适当的复制构造函数和赋值运算符,其签名是:

Polygon(const Polygon& rhs);  // copy constructor
Polygon& operator=(const Polygon& rhs); // assignment operator

这两个功能都应该实现。请看the Rule of 3获取此信息。

但是,对于 operator <operator > ,您应该向这些函数传递引用,而不是值:

friend bool operator > (Polygon& polygon1, Polygon& polygon2);
friend bool operator < (Polygon& polygon1, Polygon& polygon2);

那么复制构造函数和赋值运算符就不会起作用,因为参数类型是一个引用。


为了完整性,让我们尝试实现复制/赋值函数:

例如复制构造函数可以这样实现:

Polygon::Polygon(const Polygon& rhs) : vertices(new int[rhs.arraySize]), 
arraySize(rhs.arraySize)
{
for (int i = 0; i < arraySize; ++i)
vertices[i] = rhs.vertices[i];
}

然后对于赋值运算符,使用copy / swap idiom :

Polygon& operator=(const Polygon& rhs)
{
Polygon temp(rhs);
std::swap(temp.arraySize, arraySize);
std::swap(temp.vertices, vertices);
return *this;
}

一旦你实现了这些函数,再加上调用delete[]的析构函数,您应该不再有复制对象的问题。


其他问题:

此外,你真的应该只重载 <== , 最初使用它们的“完整”实现,并编写关于这两个运算符的其他关系运算符。

现在,您正在犯一个典型的错误,即编写一个运算符 (operator >),然后在实现 operator < 时试图将逻辑“由内而外”。 .如果 operator > 的逻辑怎么办?更复杂,yeoman 的工作弄清楚了“<”的对立面是什么?

如果你实现了 == ,然后是运算符 >就变成了:

return !(polygon1 < polygon2) && !(polygon == polygon2);  // <-- this can be further improved by implementing operator !=

关于c++ - 重载 << 运算符返回错误值 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35420036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com