• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak przekazać obiekty i tablicę obiektów do funkcji? Borland C++ Builder

0 głosów
1,021 wizyt
pytanie zadane 15 września 2015 w C i C++ przez Zikos Nowicjusz (120 p.)
edycja 15 września 2015 przez Zikos

Witam

    Piszę pewien testowy program i natrafiłem na problem z wykorzystywaniem zarówno tablicy obiektów jak i pojedynczego obiektu jako argumentu napisanej przeze mnie funkcji. Sprawy mają się tak:
    Przycisk 1 tworzy tablicę przycisków btn[] i nadaje im odpowiednie położenie, zaś przycisk 2 ma za zadanie przesuwać te utworzone przyciski. Po naciśnięciu przycisku 2 wywołuje się funkcja przesuwanie,która powinna zmieniać atrybut Left każdego z przycisków (na które wskazuje tablica) o określoną wartość, oraz zmieniać atrybut Caption na przycisku 2.
    Problem polega na tym, że podczas kompilacji Builder generuje błąd "E2451 Undefined symbol 'btn'". Co mogę zrobić, aby funkcja działała poprawnie?
    Oto kod źródłowy:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"



TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
x=true;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (x)
{

        for (int i=0; i<5;i++)
                {
                btn[i]= new TButton(this);
                btn[i]->Parent = this;
                }
        for (int i=0; i<5;i++)
         {
                btn[i]->Top=50+i*100;
         }
        x=false;
}
else
        Form1->Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        void __fastcall przesuwanie(btn,Button2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::przesuwanie(TButton btn[],TButton Button2)
{
        for (int i=0; i<5;i++)
            {
            btn[i].Left+=20;
            }
        Button2.Caption="dziala";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
for(int i =0; i<5;i++)
        delete  btn[i];
}
//---------------------------------------------------------------------------

Oraz kod nagłówkowy:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
        TButton *Button1;
        TButton *Button2;
        TPanel *Panel1;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
private:	// User declarations
public:		// User declarations
TButton * btn[5];
bool x;

      __fastcall TForm1(TComponent* Owner);
      void __fastcall przesuwanie(TButton btn[],TButton Button2);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Z góry dziękuję za wszelką pomoc :)

1 odpowiedź

0 głosów
odpowiedź 15 września 2015 przez Criss Mędrzec (171,460 p.)

Po pierwsze - masz tablice wskaźników. Przekazując w ten sposób do funkcji powinno działać, tylko że zadeklarowałeś tablice wskaźników, a wg deklaracji funkcji, argumentem ma być tablica obiektów. Ew. możesz przekazać jako wskaźnik TButton*, ale mówie - tak powinno działać.

Po drugie - w Button2Click. Dlaczego deklarujesz funkcje wewnątrz funkcji? Wiadomo o co ci chodziło, ale wywołuje się tak: przesuwanie(btn,Button2);

Edit: teraz się przyjrzałem i ty chcesz mieć tą tablice wskaźników :D To fajne, tylko dlaczego w takim razie do funkcji chcesz przekazywać tablice obiektów?

komentarz 15 września 2015 przez Zikos Nowicjusz (120 p.)

Przyznam szczerze, że jestem dość nowy w tym temacie i nie do końca orientuję się w Builderze. Próbowałem zadeklarować w pliku nagłówkowym tablicę obiektów TButton btn[5], ale generuje to błąd "Cannot find default constructor to initialize member 'TForm1::btn'" którego nie potrafię obejść. Szukam więc rozwiązania deklarując tablicę wskaźników. Nie wiem tylko jak przekazać tą tablicę do funkcji. Czy mógłbym poprosić o fragment kodu, zarówno deklarowania funckji, jak i wywoływania jej? (zapis przesuwanie(btn,Button2); nadal generuje błąd Undefined symbol 'btn'")

komentarz 16 września 2015 przez Criss Mędrzec (171,460 p.)

Możliwe, że to przez to, że argument w deklaracji i to co chcesz funkcji przekazać ma tą samą nazwe. Skąd kompilator ma wiedzieć o co ci chodzi?

Co do Cannot find default constructor to initialize member 'TForm1::btn

Powinieneś mieć zaincludowany plik w którym jest definicja klasy TButton, ale nie mam pojęcia gdzie ona jest, nigdy nic nie robiłem builderze. Inaczej kompilator nie wie czym jest TButton, a tym bardziej nie wie, że ma pole Left. Musisz po prstu zaincludować plik z definicją TButton. W zasadzie dziwne, że nie wyrzucał czegoś podobnego też przy wskaźniku - co prawda w wypadku wskaźniku wystarczy forward declaration (linijka class TButton; nad definicją klasy w której skład wchodzi ten wskaźnik), ale tego też nie widze.

komentarz 16 września 2015 przez Zikos Nowicjusz (120 p.)

Zmieniłem nazwę argumentów funkcji, i nie deklaruję już jej w wewnątrz innej funkcji, poprawiłem ten głupi błąd :) Jednak teraz kompilator generuje na linijce wywoływania funkcji błąd "E2459 VCL style classes must be constructed using operator new". Nie rozumiem dlaczego tak się dzieje, szczególnie że całą tablicę btn[] wypełniłem obiektami korzystając właśnie z operatora "new", jak widać na kodzie źródłowym.

Oto zmieniony fragment kodu:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        przesuwanie(btn,Button2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::przesuwanie(a,b)
{
        for (int i=0; i<5;i++)
            {
            a[i].Left+=20;
            }
        b.Caption="dziala";
}
//---------------------------------------------------------------------------

Mam wrażenie, że trochę błądze po omacku w tym builderze, ale wykorzystywanie tablic obiektów we własnoręcznie napisanych funkcjach wydaje mi się na tyle ważne i podstawowe, że nie może być to takie trudne :) Nie chcę więc odpuszczać, i dziękuję za wszelkie porady

komentarz 16 września 2015 przez Criss Mędrzec (171,460 p.)

Nie wiem o co chodzi, ale znalazlem jeszcze jedno niedopatrzenie w tym pierwszym kodzie (przed zmianą, do tego po zmiane zaraz dojde) - podajesz funkcji obiekt - ona go sobie  skopiuje i w oryginale nic się nie zmieni (a chcesz zmienić Caption). Dlatego przekaż jej to przez referencje (TButton& nazwa_arg), albo przez wskaźnik (TButton* nazwa_arg). Z tym że w wypadku wskaźnika odwołujesz się do składowych obiektu strzałką -> zamiast kropki. Nie wiem czy to wiesz czy nie, ale wole być pewnym. Tablice akurat można przekazać tak jak jest - funkcja i tak będzie działać na oryginale, bo przekazując tablice, przekazujesz wskaźnik.

Spróbuj tak i tak, ale w google znalazłem temat w któym komuś pomogło przekazywanie przez wskaźnik: http://bytes.com/topic/c/answers/726042-e2459-vcl-style-classes-must-constructed-using-operator

Co do tego, co zmieniłeś - fajne, że zmieniłeś nazwy, ale dlaczego a i b są pozbawione typu ? :P

Podobne pytania

+1 głos
3 odpowiedzi 236 wizyt
0 głosów
2 odpowiedzi 128 wizyt
Porady nie od parady
Nie wiesz jak poprawnie zredagować pytanie lub pragniesz poznać którąś z funkcji forum? Odwiedź podstronę Pomoc (FAQ) dostępną w menu pod ikoną apteczki.FAQ

67,112 zapytań

114,058 odpowiedzi

241,715 komentarzy

47,027 pasjonatów

Przeglądających: 198
Pasjonatów: 12 Gości: 186

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...