2017-12-01 9 views
-1

私はクラスコンストラクタで初期化される構造体を持っています。構造体のコールバックを呼び出すときにその構造体を初期化するメモリアドレスを持つポインタが必要です。それはパラメータとして持つクラスのインスタンスを送ることができます。私はTouchZone構造体を作成していButtonクラスのコンストラクタでクラスのインスタンスメモリアドレスはC++

struct TouchZone { 

    int Layer; 
    bool Active = false; 
private: 
    int Width; 
    int Height; 
    int X; 
    int Y; 
    Button *linkedButton; 
    void(*Callback)(Button &sender); 

public: 
    TouchZone() 
    { 

    } 

    TouchZone(int width, int height, int x, int y, void((*callback)(Button &sender)), int lyr = 100) 
    { 
     Width = width; 
     Height = height; 
     X = x; 
     Y = y; 
     Active = true; 
     Callback = callback; 
     Layer = lyr; 
} 

    Button* getLinkedButton() { 
     return linkedButton; 
    } 

    void resize(int width, int height, int x, int y, int lyr = -1) { 
     Width = width; 
     Height = height; 
     X = x; 
     Y = y; 
     if (lyr != -1) 
     { 
      Layer = lyr; 
     } 
    } 

    void UseCallback() { 
     Callback(*linkedButton); 
    } 

    int getX() { 
     return X; 
    } 

    int getSpanX() { 
     return X + Width; 
    } 

    int getY() { 
     return Y; 
    } 

    int getSpanY() { 
     return Y + Height; 
    } 

    bool CheckBounds(int tX, int tY) { 
     if (((tX >= this->X) && (tX <= this->getSpanX())) && ((tY >= this->Y) && (tY <= this->getSpanY()))) { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    void SetLinkedButton(Button *butt) { 
     linkedButton = butt; 
    } 

}; 

class Button { 
public: 
    int Color; 
    int layer; 
    Outline outline; 
    RectType rectType; 
    int getSpanX(); 
    int getSpanY(); 
    int getX(); 
    int getY(); 
    bool isEnabled(); 
    bool PressChecking = false; 
    void enable(); 
    void disable(); 
    void draw(); 
    void resize(int ix, int iy, int isx, int isy); 
    Button(); 
    Button(int ix, int iy, int isx, int isy, int color, void(*callback)(Button& sender), RectType bt, Outline ot, bool pressCheck); 
    static void FindButtonPressed(int x, int y); 
    TouchZone theZone; 
private: 
    String Text; 
    static LinkedList<TouchZone> YaBoisTouches; 
    int X, Y, SizeX, SizeY; 

}; 
int Button::getSpanX() { 
    return (this->X + this->SizeX); 
    } 
int Button::getSpanY() { 
    return (this->Y + this->SizeY); 
} 
int Button::getX() 
{ 
    return this->X; 
} 
int Button::getY() 
{ 
    return this->Y; 
} 
Button::Button() { 

} 
Button::Button(int ix, int iy, int isx, int isy, int color, void(*callback)(Button &sender), RectType bt, Outline ot, bool pressCheck){ 
    this->X = ix; this->Y = iy; this->SizeX = isx; this->SizeY = isy; this->outline = ot; this->rectType = bt; this->Color = color; this->PressChecking = pressCheck; 
    this->draw(); 

    theZone = TouchZone(this->SizeX, this->SizeY, this->X, this->Y, callback); 
    theZone.SetLinkedButton(this); //This is where I try to pass the specific instance of this class to the struct. 
    Button::YaBoisTouches.add(theZone); 
} 
void Button::resize(int ix, int iy, int isx, int isy) { 
    this->X = ix; this->Y = iy; this->SizeX = isx; this->SizeY = isy; 
    theZone.resize(this->SizeX, this->SizeY, this->X, this->Y); 
    this->draw(); 
} 
void Button::FindButtonPressed(int x, int y) { 
    TouchZone FoundZone; 
    int HighestLayer = 0; 
    for (int i = 0; i < Button::YaBoisTouches.size(); i++) 
    { 
     if (Button::YaBoisTouches.get(i).CheckBounds(x, y)) { 
      if (Button::YaBoisTouches.get(i).Layer > HighestLayer) { 
       HighestLayer = YaBoisTouches.get(i).Layer; 
       FoundZone = YaBoisTouches.get(i); 
      } 
     } 
    } 
    if (FoundZone.Active) { 
     if (FoundZone.getLinkedButton()->PressChecking) { 
      if (!pressed) { FoundZone.UseCallback(); } 
     } 
     else { 
      FoundZone.UseCallback(); 
     } 
    } 
} 

:ここ

はいくつかのコードです。構造体では、TouchZoneを作成したButtonクラスの特定のインスタンスへのポインタを格納しようとしています。私はコンストラクタ内でこれを正しく行う方法を理解することはできませんし、可能であるかどうかも分かりません。私がここでコンパイルしているものはコンパイルされていますが、ポインタとメモリアドレスに関する知識が不足しているため、私が望んでいない結果が得られるようです。

これは、コールバックへのButtonクラスの参照をどのように使用するかを示す関数の例です。

void HomeScreen(Button& sender) { 
    Serial.println(sender.getSpanX()); //Prints some number like 2133411092 but varies every time. Should be 200. 
    Serial.println(sender.theZone.getSpanX()); //Constantly prints 85, but should also be 200. 
    sender.disable(); 
    theScreen.fillScr(VGA_MAROON); 
    delay(300); 
    theScreen.fillScr(VGA_WHITE); 
    Serial.println(sender.getX()); //Usually prints some number like -149863422 but varies every time 
    sender.resize(sender.getX(), 10, sender.getSpanX(), sender.getSpanY()); //The button disappears on the screen, which it should not. 
    sender.enable(); 

} 

この質問は私の最初であり、あまりにも肥大化していると思います。要約すると、私の目標は、クラスのコンストラクタのの内側にあるというクラスインスタンスインスタンスの参照を渡すことです。

答えて

0

thisポインタは、コンストラクタの呼び出しが完了した後に作成されます。

ポインタは、コンストラクタ呼び出しが完了した後にのみ作成されます。コンストラクタ呼び出しが完了する前にクラスポインタを使用することはできません。 - miradham

+1

私のコメントは答えられませんでした...あなたは特定のケースの使用状況をより詳細にチェックする必要があります。 – miradham

+1

'this'ポインタはコンストラクタで有効です。オブジェクトはまだ完全に構築されていないので、*使用することはできませんが、*保存して後で使用することはできます。 –

+0

@BoPersson私はTouchZone構造体へのポインタを渡すとき、私はそれをしませんか?私は、ボタンが実際に構築され、UIに表示されるまでポインタを使用していません。 – AadamZ5

0

theZoneのコンストラクタにButtonへのポインタを渡す、またはTouchZonesetLinkedButtonクラスを追加し、Buttonコンストラクタの本体にそれを呼び出すいずれ。