我在使用这段代码时遇到问题,这些代码将评估数值运算。我试着搜索,但没有答案似乎有帮助。
表示操作的基类是:
Operacija.h:
#pragma once
#include <iostream>
using namespace std;
class Operacija
{
protected:
char* naziv;
int drugiO;
Operacija* suprotna;
public:
Operacija* retOp() { return this->suprotna; }
int retD() { return this->drugiO; }
void printOp()
{
cout << "Ime operacije: " << this->naziv << endl;
cout << "Drugi operand: " << this->drugiO << endl;
cout << "Ime suprotne operacije: " << this->suprotna->naziv << endl;
}
virtual int DoOperation(int op1, int op2) = 0;
};
此派生类用于乘法:
Mnozenje.h:
//this is .h for 1st class
#pragma once
#include "Operacija.h"
#include "Deljenje.h"
class Mnozenje : public Operacija
{
public:
Mnozenje(int b);
int DoOperation(int op1, int op2);
};
Mnozenje.cpp:
#include "Deljenje.h"
#include "Mnozenje.h"
class Deljenje;
Mnozenje::Mnozenje(int b)
{
Deljenje* a = new Deljenje(b);
naziv = "Mnozenje";
suprotna = a;
if (b == 0)
{
cout << "operand ne sme biti 0, stoga je stavljen na ";
cout << "default tj. postavljen na vrednost 1!" << endl;
drugiO = 1;
}
else
drugiO = b;
}
int Mnozenje::DoOperation(int op1, int op2)
{
int a = 0;
a = op1 * op2;
return a;
}
这个派生类是用于划分的:
Deljenje.h:
#pragma once
#include "Operacija.h"
#include "Mnozenje.h"
class Deljenje : public Operacija
{
public:
Deljenje(int a);
int DoOperation(int op1, int op2);
};
Deljenje.cpp:
#include "Deljenje.h"
#include "Mnozenje.h"
class Mnozenje;
Deljenje::Deljenje(int a)
{
Mnozenje* b = new Mnozenje(a);
naziv = "Deljenje";
suprotna = b;
if (a == 0)
{
cout << "operand ne sme biti 0, stoga je stavljen na default tj. postavljen na vrednost 1!" << endl;
drugiO = 1;
}
else
drugiO = a;
}
int Deljenje::DoOperation(int op1, int op2)
{
int a = 0;
a = op1 / op2;
return a;
}
我确实理解为什么这不起作用,我确实尝试只是声明指针而不是初始化suprotna
成员Mnozenje
和Deljenje
。但我有另一个类是类型为Operacija
的数组的容器,我不能有未初始化的指针,因为我需要使用suprotna
调用其他函数。
答案 0 :(得分:2)
您的问题引发了三个问题:
第一个是关于编译错误,因为不必要的循环拒绝。实施 NO_NAME 的答案可以完全解决此问题demonstrated here。
第二个是每次创建Mnozenje
或Deljene
时都会发生的细分错误:例如,如果您从{{1}创建Mnozenje
然后你将在构造开始时创建一个新对象int
,它将在构造开始时创建一个新的Deljenje
,它将创建...直到发生堆栈溢出。
第三个问题是您对继承的预期用途。拥有Mnozenje
而不是Operacija
的容器会导致slicing,并且注定要失败。
<强>建议:强>
我理解Operacija*
是乘法而Mnozenje
是一个除法,并且您尝试将Deljene
存储在反向操作中。
因此,我建议你预见一个带有可选参数的构造函数,这样当你创建一个反向操作时,你可以将原始操作指示为reverse。
这个想法是这样的:
suprotna
在这种情况下,您可以在相关对象之间创建循环引用,而不是永远递归。
注意: 这种解决方法会使对象的破坏稍微复杂一些。如果您有足够的时间参加考试,请考虑更改设计:
class Mnozenje : public Operacija
{
public:
Mnozenje(int b, Operacija* rev=nullptr);
int DoOperation(int op1, int op2);
};
Mnozenje::Mnozenje(int b, Operacija* rev)
{
naziv = "Mnozenje";
suprotna = rev==nullptr ? new Deljenje(b, this) : rev;
...
}
// and the same kind of change for Deljenje
和shared_ptr
进一步改进,以帮助您管理内存; weak_ptr
成员函数来避免完全创建反向操作。 答案 1 :(得分:1)
$("h2[style='color=#ccc; font-size=12px; margin=10px;']");
中的#include "Mnozenje.h"
和Deljenje.h
中的#include "Deljenje.h"
不需要Mnozenje.h
。您在.cpp
文件中使用类的事实并不意味着您必须在.hpp
文件中定义此类。
您也不需要编写类似这样的类的声明:class Deljenje;
,因为includes(例如#include "Deljenje.h"
)为您提供了这些类的定义。
似乎不太了解包含作品的事实。
这很简单。包括只将整个指定文件复制到#include
指令的位置。您可以在此处详细了解:How does the compilation/linking process work?