我知道之前已经发布了很多次,但没有一个解决方案能够提供帮助。我正在尝试从一个超类创建多个子类(在这个例子中,Value-> Fraction-> RationalFraction和Value-> Fraction-> IrrationalFraction),但我一直收到这个错误。我认为它来自循环包含,但我不知道如何在没有它的情况下使分数代码工作。当我构造Fraction时,根据构造函数,它会创建一个Irrational或Rational Fraction,但是我需要在这些子类中包含Fraction,它会创建一个集群。错误发生在RationalFraction和IrrationalFraction中,我似乎无法解决它。有没有更顺畅的方法来实现这个或至少一种方法来修复错误?对不起,如果已经回答了这个问题,我仍然是多态的新手。
Value.h
#ifndef VALUE_H
#define VALUE_H
#include <string>
using namespace std;
class Value
{
public:
Value();
virtual ~Value();
string type;
virtual string getType() = 0;
protected:
private:
virtual Value* simplify() = 0;
};
#endif // VALUE_H
Fraction.h
#ifndef FRACTION_H
#define FRACTION_H
#include "Value.h"
#include "RationalFraction.h"
#include "IrrationalFraction.h"
#include <string>
using namespace std;
class Fraction: public Value
{
private:
RationalFraction* rtF;
virtual Fraction* simplify() = 0;
IrrationalFraction* irF;
public:
Fraction(int n, int d);
Fraction(string n, int d);
virtual ~Fraction();
virtual string getType() = 0;
int numer;
int denom;
protected:
};
#endif // FRACTION_H
Fraction.cpp
#include "Fraction.h"
#include <iostream>
using namespace std;
Fraction::Fraction(int n, int d) {
rtF = new RationalFraction(n,d);
}
Fraction::Fraction(string n, int d){
irF = new IrrationalFraction(n, d);
}
Fraction::~Fraction()
{
delete rtF;
delete irF;
}
IrrationalFraction.h
#ifndef IRRATIONALFRACTION_H
#define IRRATIONALFRACTION_H
class IrrationalFraction : public Fraction
{
public:
IrrationalFraction(string n, int d);
virtual ~IrrationalFraction();
protected:
private:
IrrationalFraction* simplify();
};
#endif // IRRATIONALFRACTION_H
RationalFraction.h
#ifndef RATIONALFRACTION_H
#define RATIONALFRACTION_H
using namespace std;
class RationalFraction: public Fraction
{
public:
RationalFraction(int n, int d);
virtual ~RationalFraction();
int numer;
int denom;
protected:
private:
RationalFraction* simplify();
};
#endif // RATIONALFRACTION_H
谢谢你们!
这是错误消息:
include\RationalFraction.h|8|error: expected class-name before '{' token|
include\IrrationalFraction.h|5|error: expected class-name before '{' token|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
答案 0 :(得分:1)
1 首先,您需要使用前向类声明替换 RationalFraction.h
和IrrationalFraction.h
的包含,如下所示:
class RationalFraction;
class IrrationalFraction;
2 其次,您需要在文件Fraction.cpp
中添加这些包含。
3 第三,您需要在Fraction.h
和RationalFraction.h
中添加IrrationalFraction.h
的内容。
4 第四,您需要在这两个类中添加getType
的实现。
5 第五,为避免名称冲突等严重问题,您需要从标题中删除using namespace std;
。
6 第六,为避免双重删除,即未定义的行为,您必须禁止复制或处理复制。处理复制的一种方法是使用智能指针而不是原始指针。另一个是定义复制构造函数和复制赋值运算符(这有点过于简单,但你可以很容易地找到细节:google为“三个规则”)。
7 Fraction
的构造函数无条件地调用IrrationalFraction
的构造函数,该构造函数调用Fraction
的构造函数。这是无限递归,必须以某种方式解决。当你开始测试时,你会发现它。
这里的设计看起来非常像Java。
您是否考虑过课程模板?
答案 1 :(得分:0)
RationalFraction.h
的第8行说
class RationalFraction: public Fraction
但该文件中的任何地方都没有声明Fraction
。您 到
#include "Fraction.h"
如果您打算使用在其中声明的内容。
请注意,Fraction.h
包含RationalFraction.h
iteslf。如果你不解决这个问题,你将遇到循环标题依赖问题,这基本上意味着noithing将起作用。您可能希望使用RationalFraction
和IrrationalFraction
的前向声明,而不是包含其标题。
答案 2 :(得分:0)
我不认为你的设计非常好,但除此之外,还有一些明显的问题:
1使用尚未声明的名称,例如RationalFraction.h中的Fraction
。
2你可以使用指向对象的指针(如RationalFraction* rtF;
)而没有对象的定义:你需要的只是一个声明。
答案 3 :(得分:0)
你错过了一些&#34; #include&#34; s。
当您实现继承时,编译器期望您将从类继承。并且编译器不知道&#34;分数&#34;是一个类,因为你不包括他的.h文件
答案 4 :(得分:0)
你不能拥有像RationalFraction和Fraction这样的类来嵌入彼此。您应该使用一种名为前向声明(What are forward declarations in C++?)的技术。简而言之,这意味着您可以像下面一样声明两个类RationalFraction和IrrationalFraction,而不包括两个头文件。你需要的只是保留两个指向这些类的指针,因此指针大小是固定的并且由编译器知道(4或8个字节,取决于你的PC的处理器架构)。
#ifndef FRACTION_H
#define FRACTION_H
#include "Value.h"
#include <string>
using namespace std;
class RationalFraction;
class IrrationalFractional;
class Fraction: public Value
{
private:
RationalFraction* rtF;
virtual Fraction* simplify() = 0;
IrrationalFraction* irF;
public:
...
...
};
答案 5 :(得分:0)
您必须在RationalFraction.h和IrrationalFraction.h中包含Fraction.h。另外,当你在Fraction.h中包含RationalFraction.h和IrrationalFraction.h时,编译器碰巧找到类声明
class RationalFraction: public Fraction
在看过Fraction声明之前。您只能将完全声明的类用作基类。您可以通过在Fraction.h中声明RationalFraction和IrrationalFraction来解决这个问题:
#ifndef FRACTION_H
#define FRACTION_H
#include "Value.h"
#include <string>
using namespace std;
class RationalFraction;
class IrrationalFraction;
class Fraction: public Value
{
private:
RationalFraction* rtF;
virtual Fraction* simplify() = 0;
IrrationalFraction* irF;
public:
Fraction(int n, int d);
Fraction(string n, int d);
virtual ~Fraction();
virtual string getType() = 0;
int numer;
int denom;
protected:
};
#endif // FRACTION_H
这通知编译器有类RationalFraction和IrrationalFraction。你不能对前向声明的类型做很多事情,因为编译器不知道关于类的任何关系,特别是对象的大小。但是你可以做的是delcare指针和对它们的引用,所以对于Fraction来说这就足够了。
我不确定在基类构造函数中实例化子类时Fraction :: Fraction会发生什么。我的猜测是这是一个无限递归。我想你想要一个像工厂一样的东西,但它不会这样。