C++ 收割台护罩问题-被活活吞下
我完全不知所措:我不知道我的依赖性是如何产生的。我读了无数的帖子和博客,修改了很多次我的代码,以至于我甚至记不起什么几乎奏效了,什么没有奏效。我不断得到的不仅是重新定义的错误,还有类未定义的错误。我重做了标题保护,删除了一些错误,只是为了找到其他错误。不知何故,我把一切都归结为一个错误,但即使是那个错误在试图修复时也被打破了 你能帮我解决这个问题吗 card.cppC++ 收割台护罩问题-被活活吞下,c++,header,include-guards,C++,Header,Include Guards,我完全不知所措:我不知道我的依赖性是如何产生的。我读了无数的帖子和博客,修改了很多次我的代码,以至于我甚至记不起什么几乎奏效了,什么没有奏效。我不断得到的不仅是重新定义的错误,还有类未定义的错误。我重做了标题保护,删除了一些错误,只是为了找到其他错误。不知何故,我把一切都归结为一个错误,但即使是那个错误在试图修复时也被打破了 你能帮我解决这个问题吗 card.cpp #include <iostream> #include <cctype> #include "card.
#include <iostream>
#include <cctype>
#include "card.h"
using namespace std;
// ====DECL======
Card::Card()
{
abilities = 0;
flavorText = 0;
keywords = 0;
artifact = 0;
classType = new char[strlen("Card") + 1];
classType = "Card";
}
Card::~Card (){
delete name;
delete abilities;
delete flavorText;
artifact = NULL;
}
// ------------
Card::Card(const Card & to_copy)
{
name = new char[strlen(to_copy.name) +1]; // creating dynamic array
strcpy(to_copy.name, name);
type = to_copy.type;
color = to_copy.color;
manaCost = to_copy.manaCost;
abilities = new char[strlen(to_copy.abilities) +1];
strcpy(abilities, to_copy.abilities);
flavorText = new char[strlen(to_copy.flavorText) +1];
strcpy(flavorText, to_copy.flavorText);
keywords = new char[strlen(to_copy.keywords) +1];
strcpy(keywords, to_copy.keywords);
inPlay = to_copy.inPlay;
tapped = to_copy.tapped;
enchanted = to_copy.enchanted;
cursed = to_copy.cursed;
if (to_copy.type != ARTIFACT)
artifact = to_copy.artifact;
}
// ====DECL=====
int Card::equipArtifact(Artifact* to_equip){
artifact = to_equip;
}
Artifact * Card::unequipArtifact(Card * unequip_from){
Artifact * to_remove = artifact;
artifact = NULL;
return to_remove;
// put card in hand or in graveyard
}
int Card::enchant( Card * to_enchant){
to_enchant->enchanted = true;
cout << "enchanted" << endl;
}
int Card::disenchant( Card * to_disenchant){
to_disenchant->enchanted = false;
cout << "Enchantment Removed" << endl;
}
// ========DECL=====
Spell::Spell()
{
currPower = basePower;
currToughness = baseToughness;
classType = new char[strlen("Spell") + 1];
classType = "Spell";
}
Spell::~Spell(){}
// ---------------
Spell::Spell(const Spell & to_copy){
currPower = to_copy.currPower;
basePower = to_copy.basePower;
currToughness = to_copy.currToughness;
baseToughness = to_copy.baseToughness;
}
// =========
int Spell::attack( Spell *& blocker ){
blocker->currToughness -= currPower;
currToughness -= blocker->currToughness;
}
//==========
int Spell::counter (Spell *& to_counter){
cout << to_counter->name << " was countered by " << name << endl;
}
// ============
int Spell::heal (Spell *& to_heal, int amountOfHealth){
to_heal->currToughness += amountOfHealth;
}
// -------
Creature::Creature(){
summoningSick = true;
}
// =====DECL======
Land::Land(){
color = NON;
classType = new char[strlen("Land") + 1];
classType = "Land";
}
// ------
int Land::generateMana(int mana){
// ... //
}
concept.cpp
Conception::Conception{
Conception(){
classType = new char[11];
char = "Conception";
}
#include <iostream>
#include <cctype>
#include "list.h"
// ==========
LinkedList::LinkedList(){
root = new Node;
classType = new char[strlen("LinkedList") + 1];
classType = "LinkedList";
};
LinkedList::~LinkedList(){
delete root;
}
LinkedList::LinkedList(const LinkedList & obj)
{
// code to copy
}
// ---------
// =========
int LinkedList::delete_all(Node* root){
if (root = 0)
return 0;
delete_all(root->next);
root = 0;
}
int LinkedList::add( Conception*& is){
if (root == 0){
root = new Node;
root->next = 0;
}
else
{
Node * curr = root;
root = new Node;
root->next=curr;
root->it = is;
}
}
int LinkedList::remove(Node * root, Node * prev, Conception* is){
if (root = 0)
return -1;
if (root->it == is){
root->next = root->next;
return 0;
}
remove(root->next, root, is);
return 0;
}
Conception* LinkedList::find(Node*& root, const Conception* is, Conception* holder = NULL)
{
if (root==0)
return NULL;
if (root->it == is){
return root-> it;
}
holder = find(root->next, is);
return holder;
}
Node* LinkedList::goForward(Node * root){
if (root==0)
return root;
if (root->next == 0)
return root;
else
return root->next;
}
// ============
Node* LinkedList::goBackward(Node * root){
root = root->prev;
}
#include <iostream>
#include "player.h"
#include "list.h"
using namespace std;
Library::Library(){
root = 0;
}
Library::~Library(){
delete card;
}
// ====DECL=========
Player::~Player(){
delete fname;
delete lname;
delete deck;
}
Wizard::~Wizard(){
delete mana;
delete rootL;
delete rootH;
}
// =====Player======
void Player::changeName(const char[] first, const char[] last){
char* backup1 = new char[strlen(fname) + 1];
strcpy(backup1, fname);
char* backup2 = new char[strlen(lname) + 1];
strcpy(backup1, lname);
if (first != NULL){
fname = new char[strlen(first) +1];
strcpy(fname, first);
}
if (last != NULL){
lname = new char[strlen(last) +1];
strcpy(lname, last);
}
return 0;
}
// ==========
void Player::seeStats(Stats*& to_put){
to_put->wins = stats->wins;
to_put->losses = stats->losses;
to_put->winRatio = stats->winRatio;
}
// ----------
void Player::displayDeck(const LinkedList* deck){
}
// ================
void CardList::findCard(Node* root, int id, NodeCard*& is){
if (root == NULL)
return;
if (root->it.id == id){
copyCard(root->it, is);
return;
}
else
findCard(root->next, id, is);
}
// --------
void CardList::deleteAll(Node* root){
if (root == NULL)
return;
deleteAll(root->next);
root->next = NULL;
}
// ---------
void CardList::removeCard(Node* root, int id){
if (root == NULL)
return;
if (root->id = id){
root->prev->next = root->next; // the prev link of root, looks back to next of prev node, and sets to where root next is pointing
}
return;
}
// ---------
void CardList::addCard(Card* to_add){
if (!root){
root = new Node;
root->next = NULL;
root->prev = NULL;
root->it = &to_add;
return;
}
else
{
Node* original = root;
root = new Node;
root->next = original;
root->prev = NULL;
original->prev = root;
}
}
// -----------
void CardList::displayAll(Node*& root){
if (root == NULL)
return;
cout << "Card Name: " << root->it.cardName;
cout << " || Type: " << root->it.type << endl;
cout << " --------------- " << endl;
if (root->classType == "Spell"){
cout << "Base Power: " << root->it.basePower;
cout << " || Current Power: " << root->it.currPower << endl;
cout << "Base Toughness: " << root->it.baseToughness;
cout << " || Current Toughness: " << root->it.currToughness << endl;
}
cout << "Card Type: " << root->it.currPower;
cout << " || Card Color: " << root->it.color << endl;
cout << "Mana Cost" << root->it.manaCost << endl;
cout << "Keywords: " << root->it.keywords << endl;
cout << "Flavor Text: " << root->it.flavorText << endl;
cout << " ----- Class Type: " << root->it.classType << " || ID: " << root->it.id << " ----- " << endl;
cout << " ******************************************" << endl;
cout << endl;
// -------
void CardList::copyCard(const Card& to_get, Card& put_to){
put_to.type = to_get.type;
put_to.color = to_get.color;
put_to.manaCost = to_get.manaCost;
put_to.inPlay = to_get.inPlay;
put_to.tapped = to_get.tapped;
put_to.class = to_get.class;
put_to.id = to_get.id;
put_to.enchanted = to_get.enchanted;
put_to.artifact = to_get.artifact;
put_to.class = to_get.class;
put.to.abilities = new char[strlen(to_get.abilities) +1];
strcpy(put_to.abilities, to_get.abilities);
put.to.keywords = new char[strlen(to_get.keywords) +1];
strcpy(put_to.keywords, to_get.keywords);
put.to.flavorText = new char[strlen(to_get.flavorText) +1];
strcpy(put_to.flavorText, to_get.flavorText);
if (to_get.class = "Spell"){
put_to.baseToughness = to_get.baseToughness;
put_to.basePower = to_get.basePower;
put_to.currToughness = to_get.currToughness;
put_to.currPower = to_get.currPower;
}
}
// ----------
game.cpp——这是一个不完整的类
#include <iostream>
#include <cctype>
#include "game.h"
#include "player.h"
Battlefield::Battlefield(){
card = 0;
}
Battlefield::~Battlefield(){
delete card;
}
Battlefield::Battlefield(const Battlefield & to_copy){
}
// ===========
/*
class Game(){
public:
Game();
~Game();
protected:
Player** player; // for multiple players
Battlefield* root; // for battlefield
getPlayerMove(); // ask player what to do
addToBattlefield();
removeFromBattlefield();
sendAttack();
}
*/
#endif
list.cpp
Conception::Conception{
Conception(){
classType = new char[11];
char = "Conception";
}
#include <iostream>
#include <cctype>
#include "list.h"
// ==========
LinkedList::LinkedList(){
root = new Node;
classType = new char[strlen("LinkedList") + 1];
classType = "LinkedList";
};
LinkedList::~LinkedList(){
delete root;
}
LinkedList::LinkedList(const LinkedList & obj)
{
// code to copy
}
// ---------
// =========
int LinkedList::delete_all(Node* root){
if (root = 0)
return 0;
delete_all(root->next);
root = 0;
}
int LinkedList::add( Conception*& is){
if (root == 0){
root = new Node;
root->next = 0;
}
else
{
Node * curr = root;
root = new Node;
root->next=curr;
root->it = is;
}
}
int LinkedList::remove(Node * root, Node * prev, Conception* is){
if (root = 0)
return -1;
if (root->it == is){
root->next = root->next;
return 0;
}
remove(root->next, root, is);
return 0;
}
Conception* LinkedList::find(Node*& root, const Conception* is, Conception* holder = NULL)
{
if (root==0)
return NULL;
if (root->it == is){
return root-> it;
}
holder = find(root->next, is);
return holder;
}
Node* LinkedList::goForward(Node * root){
if (root==0)
return root;
if (root->next == 0)
return root;
else
return root->next;
}
// ============
Node* LinkedList::goBackward(Node * root){
root = root->prev;
}
#include <iostream>
#include "player.h"
#include "list.h"
using namespace std;
Library::Library(){
root = 0;
}
Library::~Library(){
delete card;
}
// ====DECL=========
Player::~Player(){
delete fname;
delete lname;
delete deck;
}
Wizard::~Wizard(){
delete mana;
delete rootL;
delete rootH;
}
// =====Player======
void Player::changeName(const char[] first, const char[] last){
char* backup1 = new char[strlen(fname) + 1];
strcpy(backup1, fname);
char* backup2 = new char[strlen(lname) + 1];
strcpy(backup1, lname);
if (first != NULL){
fname = new char[strlen(first) +1];
strcpy(fname, first);
}
if (last != NULL){
lname = new char[strlen(last) +1];
strcpy(lname, last);
}
return 0;
}
// ==========
void Player::seeStats(Stats*& to_put){
to_put->wins = stats->wins;
to_put->losses = stats->losses;
to_put->winRatio = stats->winRatio;
}
// ----------
void Player::displayDeck(const LinkedList* deck){
}
// ================
void CardList::findCard(Node* root, int id, NodeCard*& is){
if (root == NULL)
return;
if (root->it.id == id){
copyCard(root->it, is);
return;
}
else
findCard(root->next, id, is);
}
// --------
void CardList::deleteAll(Node* root){
if (root == NULL)
return;
deleteAll(root->next);
root->next = NULL;
}
// ---------
void CardList::removeCard(Node* root, int id){
if (root == NULL)
return;
if (root->id = id){
root->prev->next = root->next; // the prev link of root, looks back to next of prev node, and sets to where root next is pointing
}
return;
}
// ---------
void CardList::addCard(Card* to_add){
if (!root){
root = new Node;
root->next = NULL;
root->prev = NULL;
root->it = &to_add;
return;
}
else
{
Node* original = root;
root = new Node;
root->next = original;
root->prev = NULL;
original->prev = root;
}
}
// -----------
void CardList::displayAll(Node*& root){
if (root == NULL)
return;
cout << "Card Name: " << root->it.cardName;
cout << " || Type: " << root->it.type << endl;
cout << " --------------- " << endl;
if (root->classType == "Spell"){
cout << "Base Power: " << root->it.basePower;
cout << " || Current Power: " << root->it.currPower << endl;
cout << "Base Toughness: " << root->it.baseToughness;
cout << " || Current Toughness: " << root->it.currToughness << endl;
}
cout << "Card Type: " << root->it.currPower;
cout << " || Card Color: " << root->it.color << endl;
cout << "Mana Cost" << root->it.manaCost << endl;
cout << "Keywords: " << root->it.keywords << endl;
cout << "Flavor Text: " << root->it.flavorText << endl;
cout << " ----- Class Type: " << root->it.classType << " || ID: " << root->it.id << " ----- " << endl;
cout << " ******************************************" << endl;
cout << endl;
// -------
void CardList::copyCard(const Card& to_get, Card& put_to){
put_to.type = to_get.type;
put_to.color = to_get.color;
put_to.manaCost = to_get.manaCost;
put_to.inPlay = to_get.inPlay;
put_to.tapped = to_get.tapped;
put_to.class = to_get.class;
put_to.id = to_get.id;
put_to.enchanted = to_get.enchanted;
put_to.artifact = to_get.artifact;
put_to.class = to_get.class;
put.to.abilities = new char[strlen(to_get.abilities) +1];
strcpy(put_to.abilities, to_get.abilities);
put.to.keywords = new char[strlen(to_get.keywords) +1];
strcpy(put_to.keywords, to_get.keywords);
put.to.flavorText = new char[strlen(to_get.flavorText) +1];
strcpy(put_to.flavorText, to_get.flavorText);
if (to_get.class = "Spell"){
put_to.baseToughness = to_get.baseToughness;
put_to.basePower = to_get.basePower;
put_to.currToughness = to_get.currToughness;
put_to.currPower = to_get.currPower;
}
}
// ----------
至少你的问题之一是在“player.h”中你有 “player.h”不是合法的预处理器符号。你是说
#ifndef player_h
#define player_h
?
其次,concept.cpp不包含任何内容
第三,您的类定义在很大程度上是无效的
class Foo()
不合法,也不合法
class Foo() : public class Bar()
“()”与类名有什么关系?你在想构造器吗
还有这个
char = "Conception";
不能为类型指定值
-----帮助您清理代码的反馈-----
。选择一种风格
或者-如果您正在使用其他人的代码,请使用他们的代码
但要坚持下去
通过初始开发的软件缺陷中有很大一部分是因为它们很难发现——缺少分号,复合语句周围缺少{s,等等。C.f.“CARD_H”vs“player.H”
不一致性是大多数错误的根源
classType = new char[11];
char = "Conception";
你可能是说
classType = new char[11];
classType = "Conception";
但这是一个内存泄漏和一个等待发生的bug
name = new char[strlen(to_copy.name) +1]; // creating dynamic array
strcpy(to_copy.name, name);
您在其他地方使用的版本
classType = new ...
classType = "String";
分配一些内存,将地址存储在类类型中。然后它查找已编译的char*数组“String\0”的变量,并将其地址存储在类类型中
当类离开时,它将尝试删除静态字符串并崩溃
如果这是一个学习练习,并且您正试图学习内存管理,那么这种通用方法可能足够公平了。但是,像这样在类中放置指针的所有权肯定会导致内存泄漏和未定义的行为错误
最好将指针封装在RAII样式的类(一个拥有指针并在指针超出范围时执行删除操作的类)中。看看“std::unique_ptr”、“std::shared_ptr”和“std::weak_ptr”。出于您的目的,“std::string”可以通过消除大量管理开销来帮助您减少缺陷数量
。尽量避免将初始值设定项列表与赋值列表混合使用。
name = 0;
通常最好使用其中一种。当所有成员都可以通过这种方式初始化时,您可能可以不使用初始值设定项列表,但如果不能,则最好使用赋值
Foo() : m_a(), m_b(), m_c() { m_b = 1; m_c = 2; } // is m_a not having a value a bug or intentional?
。区分成员变量和普通变量。
name = 0;
您将遇到由于阴影而使值消失的bug:
在编译的过程中,您正在为自己设置一些不太明显的情况,这些情况似乎是数字,然后是糟糕的事情
abilities = 0;
不,我是超人,我有所有的能力
abilities = 42;
另外两种正确的方法是
name = NULL; // Traditional C++
或
你在某些地方这样做过,一致性再次让你失望
(小调,但几周后它会咬你的屁股)“it”通常用于引用“迭代器”,你可能想使用“data”或“value”或“element”。
name = 0;
。避免将类/对象的成员公开。
name = 0;
您的“Node”类看起来异常错误(析构函数同时删除上一个和下一个???),您无法通过查看该类来判断“it”指针是如何设置的,这可能是因为它发生在其他地方。您还会在哪里篡改“it”、上一个和下一个指针?封装
“康斯特”可以成为你的朋友(因为他是你屁股上的一个讨厌鬼)
if(to_get.class=“拼写”){
这将为_get.class分配“Spell”,导致内存泄漏和其他问题,然后成功--“Spell”计算为固定的const char*地址,该地址为非零,因此为真
(它也不会编译,因为'class'是一个关键字,而实际变量是'className')
您可以通过保护实际成员并仅通过精心选择的访问器公开它们来防止这种情况
const char* Class() const { return m_className; }
让我来分析一下这个问题:
const char* :- you cannot modify the contents,
Class() :- instead of to_get.class you'll use to_get.Class()
const :- this function does not have side-effects on the object
最后一部分意味着它可以用于常量对象
class Beer {
bool m_isFull;
public:
Beer() : m_isFull(true) {}
// non-const function, has side-effects (changes isFull);
void drink() { m_isFull = false; }
// const function, returns a copy of "m_isFull". you can
// change the value that's returned, but it doesn't affect us.
void isFull() const { return m_isFull; }
// example of a non-const accessor, if you REALLY want
// the caller to be able to modify m_isFull for some reason.
const bool& getIsFull() { return m_isFull; }
};
。最后:学习分离概念和算法。
name = 0;
代码中的许多错误/bug/错误似乎是因为您对某些细微差别甚至细节不是100%了解。这不是不合理的,但您需要找到一种方法来尝试语言中的一些小细节
花一点时间学习在ideone.com之类的平台上推出微程序。如果您使用的是Linux,请创建一个包含“test.cpp”和“test.h”以及Makefile的“srctest”目录
生成文件
all: srctest
srctest: srctest.cpp srctestextern.cpp srctest.h
g++ -o srctest -Wall -ggdb srctest.cpp srctestextern.cpp
srctest.cpp
#include "srctest.h"
#include <iostream>
// add your other includes here and just leave them.
int main() {
return 0;
}
srctestextern.cpp
#include "srctest.h"
// Anything you want to test having in a separate source file goes here.
如果您使用的是visual studio,请设置类似的设置
这样做的目的是让您可以在某个地方插入几行代码,并轻松地在调试器中逐步完成您正在尝试的内容
能够快速定位问题是成为一名成功程序员的关键部分,而不是一名受雇的代码猴子。包含代码始终是一个好主意,但您也需要包含错误(并确保它是来自此版本代码的错误)所以你是说有太多的错误让你无法涉过?对不起,老兄,但你需要把这归结为一个对你和我们都有利的问题-如果你最小化代码量和文件数,你可能会自己解决。@gjnave Factor
#ifndef SRCTEST_SRCTEST_H
#define SRCTEST_SRCTEST_H
// anything I want to test in a .h file here
#endif
#include "srctest.h"
// Anything you want to test having in a separate source file goes here.