试图将类作为参数传递给不同的类构造函数,但出现“转换”错误

Posted

技术标签:

【中文标题】试图将类作为参数传递给不同的类构造函数,但出现“转换”错误【英文标题】:Trying to pass class as parameter to a different class constructor, but am getting "conversion" error 【发布时间】:2018-04-18 01:54:08 【问题描述】:

所以我试图将一个类作为参数传递给另一个类(在不同的标头中)并不断收到我似乎无法调试的错误。

错误:

'wanderingSoul::wanderingSoul(wanderingSoul &&)': 无法将参数 1 从 'player' 转换为 'const warningSoul &'

主要问题在于 game.cpp 文件,在“//Battle Test”下面,我称之为“wanderingSoul wonderS(main)”。

'player'是一个类,流浪的灵魂也是一个类,我不明白的是如何正确传递/引用玩家类,因为它在传递给函数时效果很好,但不适用于这个类构造函数。

game.cpp
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include "player.h"
#include "npc.h"
#include "enemy.h"
#include "map.h"
#include "items.h"
#include "dialog.h"

/* To Do List
 * Multiple chars per battle if in party.
 * Add inventory & powers
 * Add battles
 * Finish "story" & dialogues
 * Make map
 * Add dialog trees (instead of if/else & switch/case)
 * Add relation between characters using weighted graph
 */

void battle(player plyr, enemy nme)

  std::cout << "You have entered a battle with " << nme.name << std::endl;
  while (!plyr.dead() && !nme.dead())
  

  


int roll()

  return rand() % 12 + 1;


int main()

  srand(time(NULL));
  std::string playerName;
  char optionChoice;
  int dialogChoice;
  npc Lexa("Lexa", 80, 80);

BEGIN_GAME:
  system("cls");
  std::cout << Lexa.nameText() << "Hey... Hey, are you awake now?" << std::endl;
  std::cout
      << Lexa.nameText() 
      << "I was starting to get worried. You've been out for quite some time. Do you remember your name?" 
      << std::endl;
INSERT_NAME:
  std::cout << "(Name): ";
  std::cin >> playerName;
  std::cout << Lexa.nameText() << "Huh. " << playerName << ". Is that right? (y/n)" << std::endl;
  std::cin >> optionChoice;
  if (optionChoice != 'y' && optionChoice != 'Y')
  
      //system("cls");
      std::cout << Lexa.nameText() << "Please try to remember, I need to make sure you're stable. " << std::endl;
      goto INSERT_NAME;
  

  player main(playerName);

INTRODUCTION:
  system("cls");
  //Print location
  initInfo(main, Lexa);

  //BATTLE TEST
  wanderingSoul wanderS(main);
  battle(main, wanderS.ws);

  //TRAVEL TEST

  system("pause");
  return 0;

enemy.h
#pragma once
#include <vector>
#include "powers.h"
#include "items.h"
#include "player.h"
//Need to include map?

class enemy

private:
  /**Stat Properties*********
  * Health: 0->100
  *     0 = Death/GameOver
  * Level: 1->100
  * Attack: 1->10
  * Defense: 1->10
  * Mana: 0->100
  * Affiliation: -100->100
  **************************/

  /*
  * Add inventory
  *      -list of pointers to inventory items
  * Add powers
  *      -list of pointers to powers
  */
  class currPowers //Keeps track of current powers have
  
  private:

  public:

  ;
public:
  unsigned int health, level, attackPWR, defensePWR, mana;
  int affiliation;
  std::string name;
  enemy()
  
      health = 100;
      level = 1;
      attackPWR = 1;
      defensePWR = 1;
      mana = 100;
      affiliation = 0;
  
  enemy(std::string t_name)
  
      name = t_name;
      health = 100;
      level = 1;
      attackPWR = 1;
      defensePWR = 1;
      mana = 100;
      affiliation = 0;
  
  /*
  void attack(player plyr, power pwr)
  

  
  */
  void defend()
  

  
  bool dead()
  
      if (health == 0 || level == 0)
      
          if (level == 0)
          
              std::cout << name << " had a heart attack." << std::endl;
          
          else
          
              std::cout << name << " has been defeated. Hoorah!" << std::endl;
          
          return true;
      
      return false;
  
  std::string nameText()
  
      return name + ": ";
  
;
/* ENEMY LIST
 *        STD/COMMON
 * Wandering Soul
 * Red Royal Soldier
 * Wolf (Pack)
 * B.A.R
 * Disciples
 *        UNCOMMON
 * Tech Soldier
 * Banished Mage
 * Tech Hound
 * Dark Mage
 *        RARE
 * Cyber Cyclops
 * Hellhound
 * Elite androids
 * Follower of The Void
 * Banshee
 *        BOSS
 * Mantis
 * Mary S.
 * The Summoner
 * NOX-322
 * The Void
 */

class wanderingSoul

public:
  /*
  Name: Wandering Soul
  Health: 75/100
  Level: |player level| - 1, level > 0.
  Attack:
  Defense:
  Mana:
  Affiliation:
  Powers:
  */
  enemy ws;
  int diceRoll;
  wanderingSoul(player plyr)
  
      ws.name = "Wandering Soul";
      diceRoll = roll(); //Rolling for health
      if (diceRoll == 0)
      
          ws.health = 50;
      
      else  if (diceRoll > 6)
      
          ws.health = 100;
      
      else
      
          ws.level = 75;
      
      diceRoll = roll(); //Rolling for level
      if (diceRoll == 0)
      
          ws.level = plyr.level - 1;
      
      else  if (diceRoll > 6)
      
          ws.level = plyr.level + 1;
      
      else
      
          ws.level = plyr.level;
      
  
;
播放器.h
#pragma once
#include <vector>
#include "powers.h"
#include "items.h"
#include "enemy.h"
//Need to include map?

class player

private:
  /**Stat Properties*********
  * Health: 0->100
  *     0 = Death/GameOver
  * Level: 1->100
  * Attack: 1->10
  * Defense: 1->10
  * Mana: 0->100
  * Affiliation: -100->100
  **************************/
  //Setting everything outside private for now due to needing to access variables in other classes.
  /*
  * Add inventory
  *      -list of pointers to inventory items
  * Add powers
  *      -list of pointers to powers
  */
  class currPowers //Keeps track of current powers have
  
  private:

  public:

  ;
public:
  unsigned int health, level, attackPWR, defensePWR, mana;
  int affiliation;
  std::string name;
  player(std::string t_name)
  
      name = t_name;
      health = 100;
      level = 1;
      attackPWR = 1;
      defensePWR = 1;
      mana = 100;
      affiliation = 0;
  

  void incAffiliation(bool x)
  
      if (x == true)
      
          affiliation += 5;
      
      else
      
          affiliation -= 5;
      
  

  void attack(enemy nme, power pwr)
  

  

  void defend()
  

  

  bool dead()
  
      if (health == 0)
      
          std::cout << "You are dead." << std::endl;
          return true;
      
      return false;
  

  std::string nameText()
  
      return name + ": ";
  

;

对不起,如果代码不好,有很多不需要的行,我打算尽快清理它,但想看看我是否可以与主角和敌人一起战斗,虽然我不知道是什么问题.我试图将玩家(主角)类作为参数传递的原因是因为我将敌人的统计数据基于玩家的统计数据,而我不是最好的指针和解除引用的东西,所以这很可能是一个问题.. . 无论如何,对不起,呃,代码很长,但这是我第一次尝试通过 C++ 制作一个小游戏并尝试学习新事物。 (好吧,我知道类和结构,但这是我第一次使用 c++ 进行非学校/非数据结构实现工作)

更新:删除了乱七八糟的 game.cpp 部分,发现问题是“语法错误:标识符 'player'”,所以我试图看看如何解决这个问题。

【问题讨论】:

你可以使用命名空间 std 使用的一件事,这将帮助你降低读取和解码的复杂性会更容易 @ImranHossain 不。这不是一个好建议,请参阅Why is “using namespace std” considered bad practice? 我无法在此处重现您的问题,您确定您使用的是这个确切的代码吗? 错误消息表明您正在尝试传递 player 对象,而该对象应为 wanderingSoul 对象。这是行不通的,因为player 不是从wanderingSoul 派生的。另一方面,当您定义的只是转换构造函数时,为什么编译器会尝试调用(隐式声明的)移动构造函数,我不知道。顺便说一句,您为什么将 player 对象通过值而不是通过引用传递给 wanderingSoul 构造函数?这可能有助于解决错误。 @Hamed 是的,我试着查看我的其他标题,除了wanderingSoul(player plyr) 部分之外,一切似乎都很好。 【参考方案1】:

这里的问题是您将enemy.h 包含在player.h 中,并将player.h 包含在enemy.h 中。 然后将它们都包含在您的game.cpp 中。 Circular dependency 就是这种情况。 当您尝试编译您未共享的代码时,一定会出现更多错误。

无论如何,你可以使用forward declaration来避免这个问题。

一些旁注:

由于您正在开发游戏,因此您需要了解更多关于inheritance 和composition 的信息。继承是IS-A关系的情况,另一方面组合是HAS-A的情况。

所以在这里你所做的在设计上是不正确的,Wandering Soul 是一个敌人,所以不是在wanderingSoul类内部创建一个敌人,而是从enemy类固有的.

你的敌人可以拥有多个小工具,而这些小工具可以是另一个类,所以在这里你可以看到你有一个HAS-A情况的案例,你可以从中受益作文。

另一件事是,PlayerEnemy 在您的游戏世界中是两个独立的东西,因此将玩家传递给敌人类不是一个好主意。您需要一个游戏控制器类来控制这两个类的对象之间的交互,例如打架或说话或这两者可能做的其他事情。

【讨论】:

现在看,应该是问题所在。我不完全理解它,所以我将从头开始重做我的包含以跟随我正在做的事情。 @f*** 这是个好主意,我将编辑我的问题以获取一些可用于更好设计的附注。 哇,谢谢!我仍然无法完全理解如何构建循环依赖的修复程序,因为当我在顶部执行前向声明 (enemy * nme) 时,我在 player.h 中收到错误消息“使用未定义类型'敌人'” .所以我确定我做错了什么,程序试图创建一个与它无关的新类型的对象。并感谢您提供的继承链接!我之前一直在想这个,因为我知道wanderingSoul是一个敌人,但是在学校里从来没有学过继承,也不知道如何设置它 @f*** 恕我直言,如果您以良好的设计重新开始这项任务,您将获得更好更快的结果。循环依赖是一个很难解决的问题,它几乎总是由糟糕的设计引起的。避免它而不是解决它。 哦,好吧,我会在一段时间内(或明天)做,虽然我想知道是否可以编辑子类。就像在做“class wonderingSoul:public敌人”之后,如果我可以编辑健康(超类中的属性)或者我需要做某种多继承/多级继承来实现这一点。

以上是关于试图将类作为参数传递给不同的类构造函数,但出现“转换”错误的主要内容,如果未能解决你的问题,请参考以下文章

如何将 unique_ptr 对象作为参数传递给作为库的类

我可以将类引用作为参数传递给 VB Net 中的函数吗?

如何将类方法作为参数传递给该类外部的函数?

如何将类成员函数传递给 3rd 方库中的方法?

如何将构造函数参数传递给 AppDomain.CreateInstanceXXX?

将类作为参数传递给方法,然后调用静态方法