我正在学习多态性,这是一个小游戏。我在这里有一个代表性的角色,我想编程,以便从角色中人们可以选择战士或弓箭手继续游戏。
#pragma once
#include <iostream>
using namespace std;
#include <string>
class Warrior;
class Archer;
class Character {
public:
Character(void);
~Character(void);
Character* creatCharacter(int choice, string CharacterName) {
if (choice == 1)
return (Character*)new Warrior(CharacterName);
if (choice == 2)
return (Character*)new Archer(CharacterName);
return NULL;
}
virtual void Skill_Cast() {};
};
class Warrior :public Character {
private:
string name;
public:
Warrior(void);
~Warrior(void);
Warrior(string CharacterName) {
name = CharacterName;
}
void Skill_Cast() {
cout << "Punch!" << endl;
}
};
class Archer : public Character
{
private:
string name;
public:
Archer(void);
~Archer(void);
Archer(string CharacterName) {
name = CharacterName;
}
void Skill_Cast() {
cout << "Shoot!" << endl;
}
};
在主要功能中:
int main() {
cout <<"Enter character's name: ";
string name;
getline(cin, name, '\n');
cout <<"Enter your character class by number (1),(2),(3): ";
int choice;
cin >> choice;
Character* YourChar;
YourChar = YourChar->creatCharacter(choice, name);
YourChar->Skill_Cast();
}
这是错误:
Error 1 error C2512: 'Warrior' : class has no constructors
Error 2 error C2514: 'Archer' : class has no constructors
顺便说一下,你能解释一下这些错误并帮助我解决这个错误吗?这是一种&#34;抽象工厂设计模式&#34; ?非常感谢。 (抱歉我的英语不好)
答案 0 :(得分:0)
将文件重新排列为标头/源文件。它将使您的代码更清晰,更易于阅读,它也将解决您的问题。
// Archer.h
#pragma once
#include "Character.h"
class Archer : public Character
{
public:
Archer(void);
Archer(std::string CharacterName);
~Archer(void);
void Skill_Cast();
private:
std::string name;
};
// Character.h
#pragma once
#include <string>
class Character
{
public:
Character(void);
~Character(void);
Character* creatCharacter(int choice, std::string CharacterName);
virtual void Skill_Cast() {};
};
// Character.cpp
#include "Warrior.h"
#include "Archer.h"
Character* Character::creatCharacter(int choice, std::string CharacterName)
{
if (choice == 1)
return (Character*)new Warrior(CharacterName);
if (choice == 2)
return (Character*)new Archer(CharacterName);
return NULL;
}
我还没有为你完成所有工作,但这应该指出你正确的方向。
答案 1 :(得分:0)
如果你开始使用抽象工厂(很少有用),那就做吧。你不应该有你的createChracater(在Character类中定义 - 基类不应该知道它的后代)。相反,您应该有一个单独的文件,具有单独的功能,如下所示:
CharacterFactory.h
#include <character.h>
#include <memory>
std::unique_ptr<Character> make_character(int type, std::string name);
CharacterFactory.cpp
#include <warrior.h>
#include <archer.h>
#include <stdexcept>
std::unique_ptr<Character> make_character(int type, std::string name) {
if (type == 1)
return std::unique_ptr<Character>(new Archer(name));
if (type == 2)
return std::unique_ptr<Character>(new Warrior(name));
throw std::runtime_error("Unknown character type requested!");
}
答案 2 :(得分:0)
在这个片段中......你不需要(也不应该)将派生实例强制转换回基类:
Character* creatCharacter(int choice, string CharacterName)
{
if (choice == 1)
return (Character*)new Warrior(CharacterName);
if (choice == 2)
return (Character*)new Archer(CharacterName);
return NULL;
}
要使多态性起作用,派生类必须从基类继承。看起来你的基类是“Character”,所以这段代码应该更像下面的代码。这个想法是Warrior是一个角色(因为Archer是一个角色),所以你不需要(不会)施放。
Character* creatCharacter(int choice, string CharacterName)
{
if (choice == 1)
return (new Warrior(CharacterName));
if (choice == 2)
return (new Archer(CharacterName));
return NULL;
}
使用时,只需调用您想要的角色动作即可。
例如,假设Character有方法
virtual void Character::action1(){ ... do stuff }; // body in .cc file
然后,使用warrior实例,您可以调用action1(),如下所示:
Warrior warrior;
warrior.action1(); // because warrior "is-a" 'Character'.
或者更典型地,来自Character数组中的指针。
std::vector<Character*> actionFigures;
for ( << maybe all figures in vector >> )
actionFigures[i]->action1();
如果派生实例不替换方法,则上面仅调用Character :: action1() 。
如果Warrior重新定义了action1(),那么将调用它的action1()方法版本。
还有一个更大(但非常常见)的错误,你已经开始了:多态性的一点是基类不会(不会,不能)知道可能从它派生的东西。派生类可能会在以后添加许多代码版本,可能对基类没有任何更改。 (即代码重复使用)
对于每个新派生的角色,你必须修改这个函数,重新测试一切等等(不是代码重用),这个函数是“破碎的”
这只是额外的指导,而不是为您编写代码。
祝你好运。