使用运算符重载时 C++ 意外输出
C++ unexpected output when using operator overloading
我正在尝试遍历“圆”结构(基本上是二叉树)。每个圆都有一个 centerX、centerY、radius 和两个叶节点。这些叶子要么都为空,要么都不为空。永远不会有一个null和一个not null。
我正在使用运算符重载使用 SVG 文件格式将圆打印到输出流。以下是相关代码:
circle.h:
#include <set>
#include <iostream>
using namespace std;
class Circle {
private:
double centerX, centerY, radius;
Circle* c1;
Circle* c2;
public:
static const int PAGE_DIMENSION = 200;
static const int DEFAULT_MAX_RADIUS = 15;
Circle( double x, double y, double radius, Circle* r1, Circle* r2 );
Circle( double x, double y, double radius );
Circle();
int isLeaf() const;
double getCenterX() const;
double getCenterY() const;
double area() const;
double getRadius() const;
Circle* getFirstSubcircle() const;
Circle* getSecondSubcircle() const;
bool operator<( Circle& other );
Circle* operator()( double x_in, double y_in);
Circle& operator=( Circle& rhs);
Circle* operator,( Circle& other );
double distance( Circle& rhs );
// THESE FUNCTIONS ARE NOT CLASS MEMBERS
// THEY ARE DEFINED OUTSIDE OF THE CLASS
// BUT REQUIRE ACCESS TO PRIVATE FIELDS
friend ostream& operator<<(ostream& osInput, Circle& circle);
friend ostream& operator/(ostream& osInput, Circle& circle);
friend Circle* reduce( set<Circle*>& circles);
};
circle.cpp:
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <fstream>
#include "circle.h"
using namespace std;
Circle::Circle( double x, double y, double radius, Circle* r1, Circle* r2 )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = r1;
c2 = r2;
}
Circle::Circle( double x, double y, double radius )
{
centerX = x;
centerY = y;
this->radius = radius;
}
Circle::Circle()
{
srand(time(0));
int randomX = rand() % (PAGE_DIMENSION + 1);
int randomY = rand() % (PAGE_DIMENSION + 1);
int randomRadius = rand() % DEFAULT_MAX_RADIUS + 1;
centerX = randomX;
centerY = randomY;
radius = randomRadius;
}
Circle* Circle::getFirstSubcircle() const
{
return c1;
}
Circle* Circle::getSecondSubcircle() const
{
return c2;
}
int Circle::isLeaf() const
{
if (c1 == NULL && c2 == NULL) {
return 1;
}
return 0;
}
ostream& operator/(ostream& osInput, Circle& circle)
{
if (circle.isLeaf()) {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9\"/>\n";
}
else {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5\"/>\n";
Circle* firstCircle = circle.getFirstSubcircle();
Circle* secondCircle = circle.getSecondSubcircle();
osInput / *firstCircle;
osInput / *secondCircle;
}
}
test.cpp:
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <stdlib.h>
#include "circle.h"
using namespace std;
int main( int argc, char** argv ) {
Circle* circ2_1 = new Circle(45, 65, 3);
Circle* circ2_2 = new Circle(56, 55, 3);
Circle* circ2 = new Circle(11, 21, 8, circ2_1, circ2_2);
Circle* circ3 = new Circle(7, 7, 7);
Circle* circ4 = new Circle(10, 25, 11, circ2, circ3);
cout / *circ4;
}
当我运行上面的代码时,我得到以下输出:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
以下输出是我所期望的(基于 main 中的代码):
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
如果我将 circle.cpp 中“ostream& operator/”函数中的最后几行代码切换为以下代码:
osInput / *secondCircle;
osInput / *firstCircle;
输出将是:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
同样,这不是我所期待的。问题似乎是它只是将代码中列出的第一个圆圈附加到 ostream,无论它是首先出现的“firstCircle”还是“secondCircle”。我认为它应该产生我期望的输出是错误的吗?任何指向我正确方向的想法都将不胜感激,因为我已经尝试了我能想到的一切。
对于 3 参数 Circle
构造函数,您无需初始化 c1
或 c2
成员。当您稍后尝试取消引用这些值(可能是崩溃)时,这将是未定义的行为。
我正在尝试遍历“圆”结构(基本上是二叉树)。每个圆都有一个 centerX、centerY、radius 和两个叶节点。这些叶子要么都为空,要么都不为空。永远不会有一个null和一个not null。
我正在使用运算符重载使用 SVG 文件格式将圆打印到输出流。以下是相关代码:
circle.h:
#include <set>
#include <iostream>
using namespace std;
class Circle {
private:
double centerX, centerY, radius;
Circle* c1;
Circle* c2;
public:
static const int PAGE_DIMENSION = 200;
static const int DEFAULT_MAX_RADIUS = 15;
Circle( double x, double y, double radius, Circle* r1, Circle* r2 );
Circle( double x, double y, double radius );
Circle();
int isLeaf() const;
double getCenterX() const;
double getCenterY() const;
double area() const;
double getRadius() const;
Circle* getFirstSubcircle() const;
Circle* getSecondSubcircle() const;
bool operator<( Circle& other );
Circle* operator()( double x_in, double y_in);
Circle& operator=( Circle& rhs);
Circle* operator,( Circle& other );
double distance( Circle& rhs );
// THESE FUNCTIONS ARE NOT CLASS MEMBERS
// THEY ARE DEFINED OUTSIDE OF THE CLASS
// BUT REQUIRE ACCESS TO PRIVATE FIELDS
friend ostream& operator<<(ostream& osInput, Circle& circle);
friend ostream& operator/(ostream& osInput, Circle& circle);
friend Circle* reduce( set<Circle*>& circles);
};
circle.cpp:
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <fstream>
#include "circle.h"
using namespace std;
Circle::Circle( double x, double y, double radius, Circle* r1, Circle* r2 )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = r1;
c2 = r2;
}
Circle::Circle( double x, double y, double radius )
{
centerX = x;
centerY = y;
this->radius = radius;
}
Circle::Circle()
{
srand(time(0));
int randomX = rand() % (PAGE_DIMENSION + 1);
int randomY = rand() % (PAGE_DIMENSION + 1);
int randomRadius = rand() % DEFAULT_MAX_RADIUS + 1;
centerX = randomX;
centerY = randomY;
radius = randomRadius;
}
Circle* Circle::getFirstSubcircle() const
{
return c1;
}
Circle* Circle::getSecondSubcircle() const
{
return c2;
}
int Circle::isLeaf() const
{
if (c1 == NULL && c2 == NULL) {
return 1;
}
return 0;
}
ostream& operator/(ostream& osInput, Circle& circle)
{
if (circle.isLeaf()) {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9\"/>\n";
}
else {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5\"/>\n";
Circle* firstCircle = circle.getFirstSubcircle();
Circle* secondCircle = circle.getSecondSubcircle();
osInput / *firstCircle;
osInput / *secondCircle;
}
}
test.cpp:
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <stdlib.h>
#include "circle.h"
using namespace std;
int main( int argc, char** argv ) {
Circle* circ2_1 = new Circle(45, 65, 3);
Circle* circ2_2 = new Circle(56, 55, 3);
Circle* circ2 = new Circle(11, 21, 8, circ2_1, circ2_2);
Circle* circ3 = new Circle(7, 7, 7);
Circle* circ4 = new Circle(10, 25, 11, circ2, circ3);
cout / *circ4;
}
当我运行上面的代码时,我得到以下输出:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
以下输出是我所期望的(基于 main 中的代码):
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
如果我将 circle.cpp 中“ostream& operator/”函数中的最后几行代码切换为以下代码:
osInput / *secondCircle;
osInput / *firstCircle;
输出将是:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
同样,这不是我所期待的。问题似乎是它只是将代码中列出的第一个圆圈附加到 ostream,无论它是首先出现的“firstCircle”还是“secondCircle”。我认为它应该产生我期望的输出是错误的吗?任何指向我正确方向的想法都将不胜感激,因为我已经尝试了我能想到的一切。
对于 3 参数 Circle
构造函数,您无需初始化 c1
或 c2
成员。当您稍后尝试取消引用这些值(可能是崩溃)时,这将是未定义的行为。