关于C++中的多态性
我正在学习多态性,这是一个小游戏。我这里有一个代表性的职业角色,我想编程,这样人们可以从角色中选择战士或弓箭手继续游戏关于C++中的多态性,c++,design-patterns,polymorphism,C++,Design Patterns,Polymorphism,我正在学习多态性,这是一个小游戏。我这里有一个代表性的职业角色,我想编程,这样人们可以从角色中选择战士或弓箭手继续游戏 #pragma once #include <iostream> using namespace std; #include <string> class Warrior; class Archer; class Character { public: Character(void); ~Character(void); Char
#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;
}
};
你能给我解释一下错误并帮我修正一下吗,顺便问一下,这是一种抽象的工厂设计模式吗?非常感谢。
对不起,我的英语不好请将您的文件重新排列为头文件/源文件。它将使你的代码更加清晰易读,也将解决你的问题
// 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;
}
我还没有为您完成所有的工作,但这应该为您指明了正确的方向。如果您打算使用抽象工厂,而抽象工厂很少有用,请正确操作。您不应该在角色类中定义createChracater-基类不应该知道关于其子类的任何信息。相反,您应该有一个单独的文件,具有单独的功能,如下所示: 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!");
}
在这个片段中。。。您不需要也不应该将派生实例强制转换回基类:
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,所以这段代码应该更像下面的代码。这个想法是战士是一个角色,就像弓箭手是一个角色,所以你不需要施放
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'.
或者,更典型地,来自字符数组中的指针
std::vector<Character*> actionFigures;
for ( << maybe all figures in vector >> )
actionFigures[i]->action1();
仅当派生实例不替换该方法时,上述函数才会调用Character::action1
如果Warrior重新定义action1,则将调用其版本的action1方法
还有另一个更大的错误,尽管是很常见的错误:多态性的要点是基类不应该,也不知道从它派生出什么。派生类可能会在以后的许多代码版本中添加,而基类可能不会更改。i、 e.代码重复使用
此函数是“中断”的,因为对于每个新的派生字符,您必须修改此函数、重新测试所有内容等,而不是代码重用
这只是额外的指导,而不是试图为您编写代码
祝你好运。在宣布战士和弓箭手之前,你正在使用他们。返回角色*新的WarriorCharacterName;没有必要,只需说返回新的WarriorCharacterName;还有什么是NhanVat?在YourChar->createCharacter行上,您使用的是未初始化的指针。但这并不能解释错误消息。@MohamadElghawi好吧,类是声明的,但没有定义的,所以构造函数没有声明。无论如何,这就是问题所在。YourChar=YourChar->creatCharacterchoice,name;呵呵??您正在解除未初始化指针变量的锁定?
Warrior warrior;
warrior.action1(); // because warrior "is-a" 'Character'.
std::vector<Character*> actionFigures;
for ( << maybe all figures in vector >> )
actionFigures[i]->action1();