2015-08-20 96 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 _「無論如何,這可能很有用。」_我很懷疑,如果你認爲你的鏈接包含適當的答案,請將問題標記爲僞裝。 –