关于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();