[CLI] Złe odwołanie do obiektu?

0

Kolejny problem z warcabami, po skompilowaniu i uruchomieniu programu, gdy klikamy na przycisk z pionkiem występuje komunikat

An unhandled exception of type 'System.NullReferenceException' occurred in warcaby4.exe

Additional information: Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.

A program się zamyka, problem nie występuje gdy wyłączymy z kodu poniższe 2 linijki:

ap1->polx=ap1->zwrocx1(41);
ap1->poly=ap1->zwrocy1(41);

poniżej kod klas, oraz fragment Form1:

[CIACH!]

0

Albo nie wkleiłeś jakiegoś fragmentu kodu, albo wskaźniki ap1 i ap2 na nic nie wskazują.. nic dziwnego że wywala błąd przy próbie odwołania..

0

wrzuce maina i cały form1 w takim razie bo reszta już jest, ale tam nie pisałem niczego, visual sam tworzył tą część, więc sądzę, że jest ok, jak do tej pory była:

warcaby4.cpp

#include "stdafx.h"
#include "Form1.h"

using namespace warcaby4;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew Form1());
	return 0;
}

Form1.h (cały) http://pastebin.4programmers.net/695

Edit: na nic nie wskazują... co dokładnie masz na myśli?

0
                p1 *ap1 = new p1();
                p2 *ap2 = new p2();

Czy na pewno kompiluje ci sie ten program? Nie widze definicji klasy p2

0
int p1::zwrocx1(int wart)
{
        int a;
        for(int i=8;i>0;i--)
        {
                if((i-wart)%8==0)
                {
                        a=i;
                }
        }
        return a;
}

Jaki sens jest tej funkcji skoro wyołujesz ją

zwrocx1(41)

Jak rozumiem 41 pochodzi od indeksu zmiennej button41 ale czy nie lepiej było wbic na sztywno numer kolumny skoro i tak masz osobną funkcję do obsługi każdego przycisku?. Btw Twoje wszystkie przyciski da sie obsłuzyć jedną funkcją zdarzenia onClick.

0

definicje masz w osobnym pliku. Kompiluje się na pewno, sens ma taki ze z numeru buttona wyciąga sobie współrzędne na szachownicy, dzięki czemu, moge potem odłożyć pionek na swoje miejsce jesli nie bede chcial go ruszac oraz przy sprawdzeniu czy ruch jest dozwolony (czy pole które naciskam jest po skosie sąsiadujące z polem które kliknąłem przed chwila). Skoro da się, to powiedz mi jak i czy da to pożądany efekt. Bo póki co pracuję tylko nad tym aby pionki poruszały się po szachownicy, a potrzebne jest oprogramowanie bicia figur i przekształcania pionków w damki, oprócz tego (z góry zakładam że to może nie być zrobione, ale jeśli jest jakiś prosty sposób to czemu nie) dobrze by było żeby pionki jednego koloru były zablokowane gdy drugi kolor ma turę.

PS. wybacz TEN konkretny nie kompiluje się, kompilował się gdy: p1 *ap1; p2 *ap2;

ps2: http://msdn.microsoft.com/en-us/library/z8zd05hd%28VS.80%29.aspx przy użyciu new, występuje błąd 3845, jego opis znajduje się pod tym linkiem, jednak nie rozumiem jak zaimplementować podany na MSDN kod do mojego programu, może Ty, albo ktokolwiek na forum, potrafi mi to rozjaśnić troszkę

0

offtop: jakby Ci to powiedziec.. na drugi raz, jak bedziesz miał do wklejenia wiecej linii kodu niz 10x ilosc linii tekstu postu, użyj pastebina.. to co żeś teraz machnął, to nawet cięzko bylo zaznaczyc/przewinąc/skopiować
i pacnij tak dla testu sobie EDIT na swoim poscie powyzej i podejrzyj w jaki sposob ustawia sie prawidlowo kolorowanie skladni. QUOTE sluzy do cytowan innych postow.

Co do bledu nr 3845, chodzi o to, ze w C++/CLI, przy ref-class, NIE MASZ PRAWA inicjalizowac pol obiektu "inline"owo, chyba ze dane pole jest statyczne:

http://pastebin.4programmers.net/695 napisał(a)
  1.            p1 *ap1 = new p1();
    
  2.            p2 *ap2 = new p2();
    

Przenies inicjalizacje tych pol do konstruktora, przyklad:

ref class X
{
    int poleX = 5; // ZLE, nie mozna
};

ref class Y
{
    int poleY;

    Y() // jakis konstruktor
    {
        poleY = 0;
    }
};
0

ot: czekałem tylko na ten komentarz bo sam dobrze wiedziałem że z tym kodem to jest przegięcie, ale jak czytałem posta że nie wkleiłem jakiejś części kodu to postanowiłem że tak powiem "dowalić", wezmę sobie do serca twoje rady.

A co do tematu, to nie pomogło, ale sam znalazłem rozwiązanie, zainicjalizowalem wskaźniki globalne (jeśli mówię nie poprawnie, powiedz mi proszę) w tym miejscu:

...
	using namespace System::Data;
	using namespace System::Drawing;

			 p1* ap1 = new p1();
			 p2* ap2 = new p2();

	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
...

Ale dzięki za rady i za wyrozumiałość.

0

@slowa - zainicjowalem -> zainicjalizowalem

To na pewno dziala, ale to nie jest dobre rozwiazanie. Serio, powinno to byc zrobione w konstruktorze tak jak Ci pokazalem powyzej. Czemu to "nie pomoglo"? To normalny, standardowy sposob, prawieze wszystko sie tak inicjalizuje. Jaki byl wtedy blad? inny czy ten sam? Moze wtedy kopilator sie burzyl, ze p1/p2 nie moga byc polami klasy Form1?

0

po za swoją inicjalizacją (tak myślałem że to przekręciłem) zrobiłem też to, co mówiłeś jeśli cię dobrze zrozumiałem, to ma to wyglądać tak:

p2::p2()
{
	polx=0;
	poly=0;
	kolor=0;
	nr=0;
}

. a błąd to właśnie wymieniony wyżej 3845

przy okazji, przydałby się jakiś mechanizm odwoływania się do kolejnych buttonów przez konkretne wartości zmiennych np. jak a=15 odwolanie do buttona15, do glowy przychodzi mi tylko tablica wskaźników ale nie jestem pewnien czy to dobry pomysł.

0

czekaj, nie rozumiem. jak to "poza swoja inicjalizacja"? To w koncu wywaliles tamta bledna czy nie? Jesli nie, to nie dziw ze blad masz nadal ten sam zglaszany.

Kompilator mowi Ci, ze nie masz prawa inicjalizowac pol ref-klas w ten sposob:

ref class P2
{
     int polx = 0;  // jesli masz taki zapis, inicjalizacja 'inline', w DEFINICJI KLASY, bedziesz mial blad 3845
}

MUSISZ inicjalizowac nie-inline:

ref class P2
{
     int polx;   // tutaj po porstu po nazwie pola nie ma prawa stac znak =

     p2::P2(){  polx = 0; } // inicjalizacja musi sie odbyc w konstruktorze-wewnatrz definicji klasy --- poprawnie
     P2::P2(int);  // extra konstruktor zdefiniowany zewnetrznie

     static int niespodzianka = 555;  // ale STATYCZNE pola klas mozna inicjalizowac inline.
}

P2::P2(int)
{
    polx = 0;  // albo, inicjalizacja moze tez sie odbyc w konstruktorze-zewnatrz definicji klasy --- tez poprawnie -- bo to to samo co w/w wczesniejszy konstruktor, tylko zapisane poza klasa
}
0

źle mnie zrozumiałeś, poprawiłem błąd, mam dokładnie tak jak tu piszesz, troche niejasno się wyraziłem najwidoczniej.

0

@ poprzedni post
mozliwe wyjscia:

  • tablica wskaznikow/referencji
  • przejrzec this.Controls w poszukiwaniu obiektow typu Button z dana nazwa
  • skorzystac z reflection i przejrzec pola klasy w poszukiwaniu zmiennych typu button

1 użytkowników online, w tym zalogowanych: 0, gości: 1