2015-08-20 95 views
-2

我在评估数值操作的这段代码时遇到了麻烦。我试图寻找,但没有答案似乎有帮助。通函和循环引用

基类来表示的操作是:

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成员MnozenjeDeljenje。但我有另一个类是一个Operacija类型的数组的容器,我不能有未初始化的指针,因为我需要使用suprotna调用一些其他函数。

+0

_“我这么着急,我的考试时间在10-12小时。”__那么,StackOverflow并不意味着成为通过考试的最后一招!也请看看这个可能的重复您的问题请:http://stackoverflow.com/questions/625799/resolve-circular-dependencies-in-c –

+0

我只是指出,以证明任何不清楚等等,这是就像其他任何问题一样。感谢提示! :) – MilanMarkovicDrmr

+2

虽然这是由SO的政策判断的低质量问题。无论从你的角度来看,它得到回答似乎有多紧迫。 StackOverflow用于设置长期有效的问答格式,而不是作为您的个人帮助台! –

回答

2

有您的问题提出了三个问题:

  • ,第一是关于编译错误,由于不必要的圆形refecences。实施的NO_NAME的答案完全解决了这个问题demonstrated here

  • 第二个是将要发生,你每次创建一个段错误一个MnozenjeDeljene:例如,如果从int创建Mnozenje,那么你会在它的建设新的对象开始创建权Deljenje它将在其构建开始时创建一个新的Mnozenje,这将创建...直到发生堆栈溢出。

  • 第三个问题是你打算使用继承。有一个容器Operacija而不是Operacija*将导致slicing,它注定要失败。

建议:

我明白Mnozenje是乘法和Deljene一个部门,如果您尝试在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_ptrweak_ptr来帮助您管理内存;
  • 或仅在需要时才创建反向操作(即不是在构造中,而是由于成员函数);
  • 或在您的数据结构中解耦来自操作数的操作;
  • 或者避免通过添加UndoOperation()成员函数来完全创建反向操作。
+1

我在开玩笑破坏者,我现在得到了整个事情顺利运行,谢谢你。一个简单的数组删除工作。 'delete []“var_name”' – MilanMarkovicDrmr

1

你不需要#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?

+3

这并不能解决我的问题; /但是非常感谢你的时间:) – MilanMarkovicDrmr

+0

@MilanMarkovicDrmr你有权利。尽管存在这些缺陷,程序也可以编译。我会离开这个答案。无论如何,这可能是有用的。 –

+0

@NO_NAME _“无论如何,这可能很有用。”_我很怀疑,如果你认为你的链接包含适当的答案,请将问题标记为伪装。 –