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

question-closed Błąd LNK2019 nierozpoznany zewnętrzny symbol

VPS Starter Arubacloud
0 głosów
1,173 wizyt
pytanie zadane 16 lipca 2020 w C i C++ przez grineee Bywalec (2,270 p.)
zamknięte 17 lipca 2020 przez grineee

Cześć,

uczę się obiektówki i stwierdziłem, że napisanie sobie aplikacji z paroma grami będzie ciekawe, a rozpoczęcie od gry w kółko i krzyżyk będzie proste i przyjemne (może przyjemne jest). Wyskakuje mi błąd z tematu, widziałem już kilka takich samych tematów, ale wszędzie brakowało dołączenia jakiejś biblioteki, a u mnie nie w tym leży problem (przynajmniej tak mi się wydaje). Przechodząc do sedna.

błąd:
LNK2019    nierozpoznany zewnętrzny symbol "public: void __thiscall Kolko_i_krzyzyk::uruchom_gre(void)" (?uruchom_gre@Kolko_i_krzyzyk@@QAEXXZ) przywołany w funkcji _main 

kody wszystkich plików:

#include <iostream>
#include <conio.h>
#include "Plansza.hpp"
#include "Gracz.hpp"
class Kolko_i_krzyzyk {
private:
	Plansza p1 = {};
	Gracz g1;
	Gracz g2;
	int rundy = 0;
public:
	void drukuj_wyniki() {
		if (g1.punkty >= g2.punkty) std::cout << "\n\tTABLICA WYNIKOW\nlp.\tNazwa\tWynik\n1.\t" << g1.nazwa << "\t" << g1.punkty << "\n" << "2.\t" << g2.nazwa << "\t" << g2.punkty << std::endl;
		else std::cout << "\n\tTABLICA WYNIKOW\nlp.\tNazwa\tWynik\n1.\t" << g2.nazwa << "\t" << g2.punkty << "\n" << "2.\t" << g1.nazwa << "\t" << g1.punkty << std::endl;
	}
	void uruchom_gre() {
		g1.ustaw_znak('X');
		g2.ustaw_znak('O');
		std::cout << "Podaj imiona graczy:" << std::endl;
		std::cout << "Gracz 1: ";
		std::cin >> g1.nazwa;
		std::cout << std::endl << "Gracz 2: ";
		std::cin >> g2.nazwa;
		char wybor = '0';
		while (wybor != 'j') {
			system("cls");
			menu_kolko_krzyzyk();
			wybor = _getch();
			switch (wybor)
			{
			case '1':
				rundy++;
				start_rundy();
				break;
			case '2':
				instrukcja_gry_kolko_krzyzyk();
				break;
			case '3':
				drukuj_wyniki();
				break;
			case 'j':
				std::cout << "Koniec gry w kolko i krzyzyk!" << std::endl;
				break;
			default:
				std::cout << "BLEDNY WYBOR!" << std::endl;
			}
		}
	}
	void menu_kolko_krzyzyk() {
		std::cout << "\tMenu:" << std::endl;
		std::cout << "1. Rozpocznij runde" << std::endl;
		std::cout << "2. Instrukcja gry" << std::endl;
		std::cout << "3. Tablica punktow" << std::endl;
		std::cout << "j. Zakoncz gre" << std::endl;
	}
	void instrukcja_gry_kolko_krzyzyk() {
		std::cout << "\tINSTRUKCJA:" << std::endl;
		std::cout << "Kazdy z graczy naprzemian wpisuje\nswoj znak na plansze poprzez wpisanie\ndwoch liczb oddzielonych spacja, ktore oznaczaja\nkolejno wiersz i kolumne miejsca w ktore\ndany gracz chce wpisac swoj znak.\n\nPo wybraniu zakonczenia gry wszystkie dane\nzostaja wyczyszczone (imie i punkty).\n\n";
	}
	void start_rundy() {
		Gracz* ostatni_ruch = &g1;
		int ruch = 0;
		while (!(p1.czy_wygrana()) && ruch < 9)
		{
			if ((this->rundy % 2 == 1 && ruch % 2 == 1) || (this->rundy % 2 == 0 && ruch % 2 == 0))
			{
				ostatni_ruch = &g1;
				ruch++;
				while (!(g1.wykonaj_ruch(&p1)));
			}
			else
			{
				ostatni_ruch = &g2;
				ruch++;
				while (!(g2.wykonaj_ruch(&p1)));
			}
		}
		if (ruch != 9) std::cout << "Gratulacje! Wygrywa " << ostatni_ruch->nazwa << "!" << std::endl << "Nacisnij dowolny klawisz, aby wrocic do menu..." << std::endl;
		_getch();
	}
};
#include <iostream>

class Plansza {
private:
	char plansza[3][3] = {
		{' ', ' ', ' '},
		{' ', ' ', ' '},
		{' ', ' ', ' '},
	};
public:
	void drukuj() {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (i == 0) {
					if (j == 0) std::cout << "  ";
					else std::cout << "  " << j << "  ";
				}
				else if (j == 0) std::cout << i << " ";
				else {
					std::cout << "  " << plansza[i - 1][j - 1];
					if (j != 3) {
						if (j == 1) std::cout << " |";
						else std::cout << "  |";
					}
					else std::cout << "  ";
				}
			}
			if (i == 1 || i == 2) {
				std::cout << std::endl << "  ";
				for (int j = 0; j < 3; j++) {
					if (j != 2)
					{
						if (j == 1)std::cout << "_____|";
						else std::cout << "____|";
					}
					else std::cout << "_____";
				}
			}
			if (i == 3) {
				std::cout << std::endl << "      |     |";
			}
			std::cout << std::endl;
		}
	}
	bool czy_wygrana() {
		if (plansza[0][0] == plansza[0][1] && plansza[0][1] == plansza[0][2] && (plansza[0][0] == 'X' || plansza[0][0] == 'O')) return true;
		else if (plansza[1][0] == plansza[1][1] && plansza[1][1] == plansza[1][2] && (plansza[1][0] == 'X' || plansza[1][0] == 'O')) return true;
		else if (plansza[2][0] == plansza[2][1] && plansza[2][1] == plansza[2][2] && (plansza[2][0] == 'X' || plansza[2][0] == 'O')) return true;
		else if (plansza[0][0] == plansza[1][0] && plansza[1][0] == plansza[2][0] && (plansza[0][0] == 'X' || plansza[0][0] == 'O')) return true;
		else if (plansza[0][1] == plansza[1][1] && plansza[1][1] == plansza[2][1] && (plansza[0][1] == 'X' || plansza[0][1] == 'O')) return true;
		else if (plansza[0][2] == plansza[1][2] && plansza[1][2] == plansza[2][2] && (plansza[0][2] == 'X' || plansza[0][2] == 'O')) return true;
		else if (plansza[0][0] == plansza[1][1] && plansza[1][1] == plansza[2][2] && (plansza[0][0] == 'X' || plansza[0][0] == 'O')) return true;
		else if (plansza[0][2] == plansza[1][1] && plansza[1][1] == plansza[2][0] && (plansza[0][0] == 'X' || plansza[0][0] == 'O')) return true;
		else return false;
	}
	bool wprowadz(char znak, int x, int y) {
		if (plansza[x][y] == 'X' || plansza[x][y] == 'O') {
			std::cout << "Blad! To miejsce jest juz zajete!" << std::endl;
			return false;
		}
		else {
			this->plansza[x][y] = znak;
			return true;
		}
	}
};
#include <iostream>
#include "Plansza.hpp"
class Gracz {
private:
	char znak;
public:
	std::string nazwa = "nieznane";
	int punkty = 0;
	void ustaw_znak(char xlubo) {
		this->znak = xlubo;
	}
	bool wykonaj_ruch(Plansza* p) {
		int a, b;
		std::cout << "Kolej gracza " << this->nazwa << std::endl << "Gdzie chcesz wstawic " << this->znak << "?" << std::endl;
		std::cin >> a >> b;
		if (p->wprowadz(this->znak, a, b)) return true;
		else return false;
	}
};
#pragma once
#include "Gracz.hpp"
class Kolko_i_krzyzyk {
private:
	Plansza p1;
	Gracz g1;
	Gracz g2;
	int rundy;
public:
	void drukuj_wyniki();
	void uruchom_gre();
	void menu_kolko_krzyzyk();
	void instrukcja_gry_kolko_krzyzyk();
	void start_rundy();
};
#pragma once
class Plansza {
private:
	char plansza[3][3];
public:
	void drukuj();
	bool czy_wygrana();
	bool wprowadz(char, int , int);
};
#pragma once
#include <string>
#include "Plansza.hpp"
class Gracz {
private:
	char znak;
public:
	std::string nazwa;
	int punkty;
	void ustaw_znak(char);
	bool wykonaj_ruch(Plansza*);
};
#include <iostream>
#include <string>
#include <conio.h>
#include "Kolko_i_krzyzyk.hpp"
void drukuj_menu() {
	std::cout << "Wybierz co chcesz robic :)" << std::endl;
	std::cout << "1. Zagraj w kolko i krzyzyk (2 graczy)" << std::endl;
	std::cout << "2. ----------------------" << std::endl;
	std::cout << "k. Zakoncz program" << std::endl;
}
int main()
{
	std::cout << "Witaj w giercowni!" << std::endl;
	char choice = '0';
	Kolko_i_krzyzyk k1;
	while (choice != 'k')
	{
		system("cls");
		std::cout << "Witaj w giercowni!" << std::endl;
		drukuj_menu();
		choice = _getch();
		switch (choice)
		{
		case'1':
			k1.uruchom_gre();
			break;
		case'k':
			std::cout << "Wpadnij jeszcze kiedys :)" << std::endl;
			break;
		default:
			std::cout << "BLEDNY WYBOR!" << std::endl;
		}
	}
	return 0;
}

Za każdą pomoc będę wdzięczny, po 4 godzinach szukania mam już dosyć frown

komentarz zamknięcia: problem rozwiązany
komentarz 16 lipca 2020 przez tkz Nałogowiec (42,020 p.)
Dlaczego masz dwie klasy kółko i krzyżyk? Tutaj leży błąd tak swoją drogą.
komentarz 16 lipca 2020 przez grineee Bywalec (2,270 p.)
Nie mam dwóch klas, jeden to plik .hpp, a drugi .cpp
1
komentarz 16 lipca 2020 przez tkz Nałogowiec (42,020 p.)

Wydaje mi się, że pisząc class deklarujesz klasę, a Ty robisz to dwa razy, stąd masz dwie klasy. Zmień w pliku .cpp sposób implementacji. Ogólnie powielasz ten błąd. 

https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/

http://www.math.uaa.alaska.edu/~afkjm/csce211/handouts/SeparateCompilation.pdf

komentarz 17 lipca 2020 przez Wiciorny Ekspert (277,800 p.)

@grineee,  Kolko_i_krzyzyk k1; - deklarujesz k1 ?  tutaj jest sama delaracja K1- jest null 
A gdzie tworzysz obiekt k1, zeby wywolać funkcje :)? 

komentarz 17 lipca 2020 przez grineee Bywalec (2,270 p.)
@ Wiciorny myślałem, że tworzę tam obiekt... powinienem napisać "Kolko_i_krzyzyk k1()"?

@tkz Pozmieniałem te pliki i przy kompilacji wyrzuca mi błąd, że nie mogę zainicjować wartości char [3][3] (teraz nie mam do nich dostępu, wrzucę je po 16)
komentarz 17 lipca 2020 przez tkz Nałogowiec (42,020 p.)
Jeżeli mówisz o zmiennej o nazwie plansza, to trudno byś miał do niej dostęp, skoro jest prywatna. Ale za to masz publiczne metody, które pozwalają na dostęp.
komentarz 17 lipca 2020 przez grineee Bywalec (2,270 p.)
Zmieniłem na publiczną, nie szło

Dodałem inicjalizację w konstruktorze, też nie szło

Dodałem inicjalizację w osobnej funkcji, też nie szło

Dodałem inicjalizację w funkcji Kolko_i_krzyzyk::uruchom_gre(), też nie szło

i wtedy niestety musiałem wyjść do pracy :/

1 odpowiedź

+1 głos
odpowiedź 17 lipca 2020 przez Wiciorny Ekspert (277,800 p.)
wybrane 17 lipca 2020 przez grineee
 
Najlepsza

Szablon, czyli przepis na klasę, deklarujesz i definiujesz w nagłówku. Nie używasz do niego plików .cpp. Czyli w Twoim przypadku - przenieś definicje konstruktora do nagłówka i usuń plik .cpp.

komentarz 17 lipca 2020 przez grineee Bywalec (2,270 p.)
mógłbyś na podstawie klasy Gracz (jest najmniejsza) wrzucić mi tutaj  jak wg Ciebie powinno to wyglądać?
1
komentarz 17 lipca 2020 przez grineee Bywalec (2,270 p.)

@Wiciorny, dzięki wielkie, wszystko już działa, jakbyś miał czas i ochotę, to możesz mi jeszcze nawrzucać co robię źle (wiem, że Polacy to lubią :D:D)

całość tutaj

komentarz 17 lipca 2020 przez Wiciorny Ekspert (277,800 p.)
broń boże nie chodzi o to żeby kogoś ZJECHAĆ itd, ale sceptyka na początku drogi jest dobrą nauką na przyszłość, ja się dalej ucze pokory :D

Podobne pytania

0 głosów
1 odpowiedź 655 wizyt
+1 głos
2 odpowiedzi 2,468 wizyt
0 głosów
3 odpowiedzi 5,502 wizyt

93,079 zapytań

142,042 odpowiedzi

321,449 komentarzy

62,424 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...