• 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
894 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,000 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,000 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 (269,120 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,000 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 (269,120 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 (269,120 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ź 511 wizyt
+1 głos
2 odpowiedzi 2,151 wizyt
0 głosów
3 odpowiedzi 4,903 wizyt

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...