简体   繁体   English

关于C ++中的多态

[英]About Polymorphism in C++

I'm learning about polymorphism and this is a small game. 我正在学习多态性,这是一个小游戏。 I have a representative class Character here, I want to program so that from a Character people can choose Warrior or Archer to continue the game. 我在这里有一个代表人物角色,我想要编程,以便人们可以从角色中选择“战士”或“弓箭手”来继续游戏。

#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;
   }

};

In the main function: 在主要功能中:

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();
}

And this is ERRORS: 这是错误:

 Error  1   error C2512: 'Warrior' : class has no constructors  
 Error  2   error C2514: 'Archer' : class has no constructors   

Can you explain me the errors and help me fix that, by the way, Is this a kind of "Abstract Factory Design Pattern" ? 顺便说一下,您能解释一下这些错误并帮助我解决吗,这是一种“抽象工厂设计模式”吗? Thanks so much. 非常感谢。 (sorry for my bad English) (对不起,我的英语不好)

Rearrange your files into header/source files. 将文件重新排列为头文件/源文件。 It will make your code much cleaner and easier to read and it will also solve your problem. 这将使您的代码更清晰,更易于阅读,也可以解决您的问题。

// 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;
}

I haven't done all the work for you but this should point you in the right direction. 我还没有为您完成所有工作,但这应该为您指明正确的方向。

If you are set on using Abstract Factory (which is rarely useful), do it right. 如果您打算使用Abstract Factory(这很少有用),请正确执行。 You should not have your createChracater (defined within Character class - base class should not know anything about it's descendants). 您不应该具有createChracater(在Character类中定义-基类对其后代一无所知)。 Instead, you should have a separate file, with separate function, like following: 相反,您应该有一个具有单独功能的单独文件,如下所示:

CharacterFactory.h CharacterFactory.h

#include <character.h>
#include <memory>
std::unique_ptr<Character> make_character(int type, std::string name);

CharacterFactory.cpp 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!");
}

In this snippet ... you need not (and should not) cast the derived instance back to the base class: 在此代码段中……您无需(也不应)将派生实例强制转换回基类:

Character* creatCharacter(int choice, string CharacterName) 
{
    if (choice == 1)
        return (Character*)new Warrior(CharacterName);

    if (choice == 2)
        return (Character*)new Archer(CharacterName);
   return NULL;
}

For polymorphism to work, your derived classes must inherit from the base. 为了使多态性起作用,您的派生类必须从基类继承。 It looks like your base class is "Character", so this code should be more like the following. 看起来您的基类是“字符”,因此此代码应更像以下代码。 The idea is that Warrior is-a Character (as Archer is-a Character), so you need not (shall not) cast. 这个想法是,战士是-角色(就像弓箭手是-角色),所以您不需要(也不必)施法。

Character* creatCharacter(int choice, string CharacterName) 
{
    if (choice == 1)
        return (new Warrior(CharacterName));

    if (choice == 2)
        return (new Archer(CharacterName));

   return NULL;
}

When used, simply invoke the Character action you wish. 使用时,只需调用所需的Character操作。

For example, assume Character has the method 例如,假设Character具有方法

virtual void Character::action1(){ ... do stuff };  // body in .cc file

Then, with a warrior instance, you can invoke action1() as in: 然后,使用战士实例,您可以像下面这样调用action1():

Warrior warrior;
warrior.action1();   // because warrior "is-a" 'Character'.

Or, more typically, from a pointer in an array of Character. 或者,更典型地,从字符数组中的指针开始。

std::vector<Character*>  actionFigures;

for ( << maybe all figures in vector >> )
   actionFigures[i]->action1();  

The above invokes Character::action1() only if the derived instance does not replace the method. 当派生实例不替换该方法时,以上才调用Character :: action1()。

If Warrior re-defines action1(), then its version of the action1() method will be invoked. 如果Warrior重新定义action1(),则将调用其action1()方法的版本。


There is also another somewhat bigger (though very common) mistake you have started down: the point of polymorphism is that the base class does NOT (shall NOT, CAN NOT) know what might be derived from it. 您还开始遇到另一个更大(尽管很常见)的错误:多态性的要点是基类不(应该,不能)不能知道可能从该类派生什么。 Derived classes might be added many code versions later, with possibly NO changes to the base class. 派生类可能会在以后添加许多代码版本,而基类可能没有任何更改。 (ie code re-use) (即代码重用)

This function is 'broken' in the sense that for every new derived Character you will have to modify this function, re-test everything, etc. (not code re-use) 从某种意义上说,此功能是“中断的”,即对于每个新派生的角色,您都必须修改此功能,重新测试所有内容,等等(而不是重复使用代码)


This is just additional guidance, not trying to write the code for you. 这只是额外的指导,并非试图为您编写代码。


Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM