0
class Fraction {
public:
    Fraction();
    Fraction(int);
    Fraction(int, int);
    ~Fraction();
    void setNum(int);
    void setDenom(int);
    int getNum(void) const;
    int getDenom(void) const;
    void print(void);
private:
    int num;
int denom;
};

class Circle {
public:
    Circle();
    Circle(Fraction& arg1);
   ~Circle();
    void print(void);
protected:
    Fraction *radius;
};

#include "Fraction.h"
#include "Circle.h"
#include <iostream>
using namespace std;

Fraction::Fraction() {
    num = 0;
    denom = 1;
}
Fraction::Fraction(int n, int d) {
    num = n;
    denom = d;
}
Fraction& Fraction::operator=(const Fraction& arg) {
    num = arg.num;
    denom = arg.denom; 
    return *this;
}
Fraction::~Fraction() {
}

//Circle

Circle::Circle() {
    radius->setNum(1);
    radius->setDenom(1);
}
Circle::Circle(Fraction& arg1) {
    radius->setNum(arg1.getNum());
    radius->setDenom(arg1.getDenom());
}
Circle::~Circle() {
     delete this->radius;
}

当我在 main() 中创建对象时,问题就来了

 Fraction* fPtr = new Fraction(4, 1);
 Circle* cPtrA = new Circle(*fPtr);

这两个都是类。首先,我使用复制构造函数将 classFraction 的 Numerator 设置为 4,将 Denominator 设置为 1。

然后我想将 (4, 1) 传递到我的 classCircle 但我通过调试器收到未处理异常的错误

4

2 回答 2

2

在下面的构造函数中,您没有为radius

Circle::Circle(Fraction& arg1) {
    radius->setNum(arg1.getNum());
    radius->setDenom(arg1.getDenom());
}

有不同的选项,但如果你想在 中拥有 的副本FractionCircle你可以这样做:

Circle::Circle(Fraction& arg1) : radius(new Fraction(arg1)) {
}

可能最好只存储对象的副本

class Circle {
public:
    Circle();
    Circle(const Fraction& arg1);
   ~Circle();
    void print(void);
protected:
    Fraction radius;
};

Circle::Circle(const Fraction& arg1) : radius(arg1)) {
}

请注意,通过使参数成为const引用,您可以向编译器和其他用户表明Fraction调用不会更改传递的参数。

于 2013-05-23T10:02:53.887 回答
1

您忘记radius在复制构造函数和默认构造函数中进行初始化。当您尝试调用setNum或时,这会导致异常setDenom。您可以通过分配如下所示的Fractionfor来解决此问题。radius

Circle::Circle() : radius(new Fraction())
{
    radius->setNum(1);
    radius->setDenom(1);
}

Circle::Circle(const Fraction &other) : radius(new Fraction())
{
    radius->setNum(arg1.getNum());
    radius->setDenom(arg1.getDenom());
}

习惯上,通常也更喜欢radius通过复制构造进行初始化。

Circle::Circle(const Fraction &other) : radius(new Fraction(other))
{
}

请记住删除析构函数中的对象。

Circle::~Circle()
{
    delete radius;
}

radius您可以通过按值而不是按指针存储来消除分配。

于 2013-05-23T10:02:54.817 回答