線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1179
推到 Plurk!
推到 Facebook!

二維陣列類別的解構問題

答題得分者是:anpino
khaupe
一般會員


發表:28
回覆:25
積分:15
註冊:2003-06-30

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-04-19 04:35:59 IP:61.231.xxx.xxx 未訂閱
我試著將矩陣(二維陣列)做成類別 , 但遇上了些困擾 , 目前是懷疑問題出在解構 , 附上主要程式碼 , 麻煩高手幫我看一下 , 謝謝    class Array2D{ private: int Column , Row ; float **DefaultArray2D ; void Create(int , int) ;       //在建構子中用來指派記憶體     public: static int Array2DCount ;           Array2D(int , int) ; Array2D(const Array2D &) ;            //拷貝建構子 ~Array2D() ;     Array2D operator+(float) ;            //此為純量加法 Array2D operator=(const Array2D &);   //重載指派運算子 float* operator[](int i){return DefaultArray2D[i];}//重載"[]" };    //初始化靜態變數 int Array2D::Array2DCount = 0 ; //定義Create用以配置DefaultArray2D的記憶體 void Array2D::Create(int col , int row){ Column = col , Row = row ; DefaultArray2D = new float* [Column] ;//這裡是簡單的二維陣列的寫法 for(int i = 0 ; i < Row ; i ){ DefaultArray2D[i] = new float [Row] ; } return ; } //定義建構函數 Array2D::Array2D(int col , int row){ Create(col , row) ; Array2DCount ; } //定義拷貝建構子 Array2D::Array2D(const Array2D &OldM){ Create(OldM.Column , OldM.Row) ; for(int i = 0 ; i < Column ; i ){ for(int j = 0 ; j < Row ; j ){ DefaultArray2D[i][j] = OldM.DefaultArray2D[i][j] ; } } return ; } //定義解構函數 Array2D::~Array2D(){ for(int i = 0 ; i < Column ; i ){ delete[] DefaultArray2D[i] ; } //delete[] DefaultArray2D ; //不懂為何這裡無法delete掉DefaultArray2D Array2DCount-- ; } //重載運算子 Array2D Array2D::operator=(const Array2D& M2){ for(int i = 0 ; i < Column ; i ){ for(int j = 0 ; j < Row ; j ){ DefaultArray2D[i][j] = M2.DefaultArray2D[i][j] ; } } return *this ; } 再來是我在Unit1.cpp中拉兩個按鈕 , 一個顯示目前的Array2DCount值 , 另一個則用來測式重載後的"=" 分別如下: void __fastcall TForm1::Button1Click(TObject *Sender) { Form1->Canvas->TextOutA(20 , 300 , "目前存在有" IntToStr(Array2D::Array2DCount) "個Array2D") ; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { Form1->Canvas->Refresh(); Array2D M1(2,3) ; // 1.0 2.3 M1[0][0] = 1.0 ; // 2.0 3.0 M1[1][0] = 2.3 ; // 3.14159 1.41426 M1[0][1] = 2.0 ; M1[1][1] = 3.0 ; M1[0][2] = 3.14159 ; M1[1][2] = 1.41426 ; Array2D M2(2 , 3) ; M2 = M1 ; //以下迴圈只是秀出M2的內容罷了 for(int i = 0 ; i < 2 ; i ){ for(int j = 0 ; j < 3 ; j ){ Form1->Canvas->TextOutA(50 i*100 , 100 j *20 , FloatToStr(M2[i][j])) ; } } //這裡用了兩個成員函式讀出在private裡的值 , 我想問題並不在這 , 恕略去此二函式內容 Form1->Canvas->TextOutA(20 , 250 , "col = " IntToStr(M2.column()) " , row = " IntToStr(M2.row())); } 這程式compile可以過 , 但Button2按個兩三次就出錯了 , 且觀察Array2DCount的值 , 似乎是建構與解構之間不太對勁 , 出現的錯誤訊息好像是因為指標指到錯誤的記憶體位置 [b]

我目前使用上的問題是出在"="重載的功能有問題(其實" "也有類似問題 , 但因看起來像是同一原因 , 因此打算另一個留著自己想) , 雖說覺得解構部份怪怪的 , 但也有可能是我觀念不清吧

[b] 在下功力有限 , 實在無法確實抓出錯誤何在 , 懇請板上高手提點一二 . 發表人 - khaupe 於 2004/04/19 04:46:47 發表人 - khaupe 於 2004/04/19 04:49:19 發表人 - khaupe 於 2004/04/19 05:02:08
anpino
版主


發表:31
回覆:477
積分:231
註冊:2003-01-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-04-19 10:20:30 IP:218.32.xxx.xxx 未訂閱
class Array2D{ private: int Column , Row ; float **DefaultArray2D ; void Create(int , int) ; //在建構子中用來指派記憶體     public: static int Array2DCount ;      Array2D(int , int) ; Array2D(const Array2D &) ; //拷貝建構子 ~Array2D() ;     Array2D operator+(float) ; //此為純量加法 Array2D operator=(const Array2D &); //重載指派運算子 error:float* operator[](int i){return DefaultArray2D[i];}//重載"[]" }; for example. M1[0][0] = 1.0 ; // 2.0 3.0 operator[]回傳DefaultArray2D[0],M1[0][0]=1.0這一行實際上做的是將DefaultArray2D[0](type is float*)的值改成1.0,也就是說DefaultArray2D[0]指向位址為1.0的記憶區。所以Button2按第2次時就變成存取1.0(DefaultArray2D[0])這個不合法位址。 ps.
void Array2D::Create(int col , int row){
   Column = col , Row = row ;       DefaultArray2D = new float* [Column] ;
  for(int i = 0 ; i < Column; i  ){
   DefaultArray2D[i] = new float [Row] ;
  }     return ;
}    
Solution:
class Array2D
{
...
public:
...
      float& operator()(int i,int j);
      float operator()(int i,int j)const;
};
float& Array2D::operator()(int i,int j)
{
        if (i >= Column || j >= Row)
                throw "Matrix subscript out of bounds";
        return DefaultArray2D[i][j];
}
float Array2D::operator()(int i,int j)const
{
        if (i >= Column || j >= Row)
                throw "Matrix subscript out of bounds";
        return DefaultArray2D[i][j];
}    void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Form1->Canvas->Refresh();            Array2D M1(2,3) ;
        M1(0,0) = 1.0 ;
        M1(1,0) = 2.3 ;
        M1(0,1) = 2.0 ;
        M1(1,1) = 3.0 ;
        M1(0,2) = 3.14159 ;
        M1(1,2) = 1.41426 ;            for(int i = 0 ; i < 2 ; i  )
        {
                for(int j = 0 ; j < 3 ; j  )
                {
                        Form1->Canvas->TextOutA(50   i*100 , 100   j *20 , FloatToStr(M1(i,j))) ;
                }
        }
}
------------------------------- 數學系是內功很強(邏輯/分析) 資工系是招式很多(程式技巧) 就像令狐沖
khaupe
一般會員


發表:28
回覆:25
積分:15
註冊:2003-06-30

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-04-19 23:55:17 IP:140.115.xxx.xxx 未訂閱
感謝 , 現在基本功能寫得差不多了 , 有空再繼續寫數值運算的部份吧
系統時間:2024-11-23 13:02:51
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!