如何定义构造函数 C++
How to define constructor c++
我现在只使用 C++ 一年,我希望通过我当前的项目更好地理解抽象。我根据我的书 'Beginning C++ Through Game Programming' 创建了一个 Black Jack 纸牌游戏。游戏运行正常,但我正在处理重新启动游戏、添加分数并允许您通过 fstream 查看分数的菜单选项。
这是继承自基础的菜单部分的样子 class 游戏:
class Menu
{
public:
Menu();
~Menu();
private:
Game m_game;
//saves scores to fstream from class Player m_player;
//menu options
void choice();
};
Menu::Menu() {} //no appropriate default constructor available for Game
Menu::~Menu() {}
void Menu::choice()
{
char respond;
bool run = true;
cout << "Would you like to [R]estart the game, [A]dd new score, [V]iew the score sheet or [Q]uit?" << endl;
cin >> respond;
switch (respond)
{
case 'R': m_game.play(); break;
case 'A': //add new score to fstream
case 'V': //view score txt file
case 'Q': run = false; break;
}
}
我对如何为这一部分创建默认构造函数感到非常困惑,即使是书中的示例也是如此。
游戏 class 的构造函数如下所示:
class Game
{
public:
Game(const vector<string>& names);
~Game();
//plays game
void play();
private:
Deck m_deck;
House m_house;
vector<Player> m_players;
};
我希望得到解释或示例。感谢您的帮助!
您的菜单 class(在调用构造函数之前)想要使用默认构造函数(不带参数)创建一个 Game 实例,但是 Game class 没有默认构造函数(因为如果您创建任何构造函数,默认构造函数不会自动创建)。
您有三个选择:
- 在您的游戏 class 中的当前构造函数旁边提供一个空构造函数,用于获取字符串向量。
- 使
Game m_game;
成为 Game m_game = Game(vector<string>());
。这将在构造函数之前执行,这使您能够设置任何 class 成员的默认值。此解决方案的缺点是将调用复制构造函数(首先,将创建临时对象,然后将其复制到您的实例,它可以由编译器优化,但并非总是如此;如果您不知道它是什么,检查这个:https://www.geeksforgeeks.org/copy-constructor-in-cpp/)
- 使用 C++ 中称为初始化列表的东西。本主题中有一些关于堆栈溢出的问题,例如这里(C++ - No appropriate default constructor available)。在此解决方案中,您不创建任何时间对象(如第一个解决方案)。你的构造函数看起来像这样:
Menu::Menu() : m_game(vector<string>()) {}
.
第一个和第三个选项最好。您必须决定使用哪一个。
你当然可以用非空向量替换vector<string>()
。
你也应该看看这里:https://www.learncpp.com/cpp-tutorial/constructor-member-initializer-lists/。关于初始化列表的一切都有解释。
这里的另一个问题是您不应该在菜单 class 中创建游戏实例(这是一个架构错误)。例如,您可以将指针或引用传递给 choice() 方法或 Menu class 构造函数并仅存储 Game 实例地址(如果 Game 实例将被多个方法使用,则使用后者)。更合适的方法是游戏包含一个菜单实例。
我现在只使用 C++ 一年,我希望通过我当前的项目更好地理解抽象。我根据我的书 'Beginning C++ Through Game Programming' 创建了一个 Black Jack 纸牌游戏。游戏运行正常,但我正在处理重新启动游戏、添加分数并允许您通过 fstream 查看分数的菜单选项。
这是继承自基础的菜单部分的样子 class 游戏:
class Menu
{
public:
Menu();
~Menu();
private:
Game m_game;
//saves scores to fstream from class Player m_player;
//menu options
void choice();
};
Menu::Menu() {} //no appropriate default constructor available for Game
Menu::~Menu() {}
void Menu::choice()
{
char respond;
bool run = true;
cout << "Would you like to [R]estart the game, [A]dd new score, [V]iew the score sheet or [Q]uit?" << endl;
cin >> respond;
switch (respond)
{
case 'R': m_game.play(); break;
case 'A': //add new score to fstream
case 'V': //view score txt file
case 'Q': run = false; break;
}
}
我对如何为这一部分创建默认构造函数感到非常困惑,即使是书中的示例也是如此。
游戏 class 的构造函数如下所示:
class Game
{
public:
Game(const vector<string>& names);
~Game();
//plays game
void play();
private:
Deck m_deck;
House m_house;
vector<Player> m_players;
};
我希望得到解释或示例。感谢您的帮助!
您的菜单 class(在调用构造函数之前)想要使用默认构造函数(不带参数)创建一个 Game 实例,但是 Game class 没有默认构造函数(因为如果您创建任何构造函数,默认构造函数不会自动创建)。
您有三个选择:
- 在您的游戏 class 中的当前构造函数旁边提供一个空构造函数,用于获取字符串向量。
- 使
Game m_game;
成为Game m_game = Game(vector<string>());
。这将在构造函数之前执行,这使您能够设置任何 class 成员的默认值。此解决方案的缺点是将调用复制构造函数(首先,将创建临时对象,然后将其复制到您的实例,它可以由编译器优化,但并非总是如此;如果您不知道它是什么,检查这个:https://www.geeksforgeeks.org/copy-constructor-in-cpp/) - 使用 C++ 中称为初始化列表的东西。本主题中有一些关于堆栈溢出的问题,例如这里(C++ - No appropriate default constructor available)。在此解决方案中,您不创建任何时间对象(如第一个解决方案)。你的构造函数看起来像这样:
Menu::Menu() : m_game(vector<string>()) {}
.
第一个和第三个选项最好。您必须决定使用哪一个。
你当然可以用非空向量替换vector<string>()
。
你也应该看看这里:https://www.learncpp.com/cpp-tutorial/constructor-member-initializer-lists/。关于初始化列表的一切都有解释。
这里的另一个问题是您不应该在菜单 class 中创建游戏实例(这是一个架构错误)。例如,您可以将指针或引用传递给 choice() 方法或 Menu class 构造函数并仅存储 Game 实例地址(如果 Game 实例将被多个方法使用,则使用后者)。更合适的方法是游戏包含一个菜单实例。