Итак, у меня проблема с этим назначением класса, мы настроены на код игры в стиле «крестики-нолики». Я подумал, что было бы неплохо иметь 2 версии, такие как оригинал, с 3 по ширине, а затем с 4 по горизонтали. Итак, вот базовый класс с проблемными функциями
Вот минимум, который не оставляет ничего вырезанного
Main.cpp
#include "tic_tac_toe.h"
#include "tic_tac_toe_3.h"
#include "tic_tac_toe_4.h"
int main()
{
std::vector <std::reference_wrapper<Tic_tac_toe>> games;
string playerOption{ "" };
bool isRunning{ true }, error{ true };
int position{ 0 }, playerInt{ 0 };
char option{ ' ' };
//main loop
while (isRunning)
{
cout << "Tic Tac Toe game 3 or 4: ";
cin >> playerInt;
if (playerInt == 3)
{
cout << "Executing tic tac toe 3";
Tic_tac_toe_3 game3;
games.push_back(game3);
}
else if (playerInt == 4)
{
cout << "Executing tic tac toe 4";
tic_tac_toe_4 game4;
games.push_back(game4);
}
//allows for constant looping to get user to input X or O. So program wont blow up
while (error)
{
cout << "Player 1, X or O: ";
cin >> playerOption;
try
{
games[games.size() - 1].get().start_game(playerOption); //the .get gets the stored reference
error = false;
cout << "\n"; //to add a break in the text
}
catch (Error e)
{
cout << e.get_message();
}
}
try
{
cin >> games[games.size() - 1].get(); //FAIL POINT IMO
cout << games[games.size() - 1].get();
}
catch(Error e)
{
cout << e.get_message();
}
}
return 0;
}
Tic_tac_toe.h
#include vector
using std::string;
class Tic_tac_toe
{
public:
Tic_tac_toe(int size) : pegs(size* size, " ") { } //multiply 3 or 4 by itself for 9 or 16
void start_game(std::string first_player);
void mark_board(int position);
friend std::ostream& operator<<(std::ostream& out, const Tic_tac_toe& t);
friend std::istream& operator>>(std::istream& in, Tic_tac_toe& b);
string get_player() const { return player; }
string get_winner() const { return winner; }
protected:
std::vector<string> pegs; //initializes a vector of x elements with each being a space.
private: //most logic goes within the private functions
void set_next_player();
string player;
}
Tic_tac_toe.cpp
{
void Tic_tac_toe::start_game(std::string first_player)
{
if (first_player == "X" || first_player == "O")
{
player = first_player;
clearBoard();
}
else { throw Error("Player must be X or O\n"); }
}
void Tic_tac_toe::mark_board(int position)
{
if (position < 1 || position > 9)
{
throw Error("Position must be 1 to 9.\n");
}
else if (player == "")
{
throw Error("Must start game first.\n");
}
else
{
pegs[(position - 1)] = player; //minus one for the index
set_next_player();
}
}
std::ostream& operator<<(std::ostream& out, const Tic_tac_toe& b)
{
std::cout << "\n"; //formatting purposes
for (std::size_t i = 0; i < 9; i += 3) // += 3 for new row
{
out << b.pegs[i] + " | " + b.pegs[i + 1] + " | " + b.pegs[i + 2] + "\n";
}
return out;
}
std::istream& operator>>(std::istream& in, Tic_tac_toe& b)
{
std::cout << "Pegs size" << b.pegs.size();
int pos{ 0 };
std::cout << "Player " << b.get_player() << " enter a position: ";
in >> pos;
b.mark_board(pos);
return in;
}
}
Tic_tac_toe_4 // 4 и 3 точно такие же банкоматы
class Tic_tac_toe_4 : public Tic_tac_toe
{
public:
tic_tac_toe_4() : Tic_tac_toe(4) { std::cout << "Passing to constructor"; }
}
1 ответ
Ваша программа имеет неопределенное поведение, потому что вы нажимаете ссылки на локальные переменные, такие как
Tic_tac_toe_3 game3;
В games
. Когда эти переменные покидают свою область видимости, ссылки в games
становятся недействительными, и попытка использовать их позже будет иметь неопределенное поведение.
Если вам нужен контейнер, который владеет объектами Tic_tac_toe
, используйте
std::vector<std::unique_ptr<Tic_tac_toe>>
Вместо этого в качестве типа и создайте объекты с помощью std::make_unique
. Тогда объекты будут жить до тех пор, пока принадлежащие им векторные элементы не будут уничтожены.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .