-3

I'm totally at wit's end: I can't figure out how my dependency issues. I've read countless posts and blogs and reworked my code so many times that I can't even remember what almost worked and what didnt. I continually get not only redefinition errors, but class not defined errors. I rework the header guards and remove some errors simply to find others. I somehow got everything down to one error but then even that got broke while trying to fix it.

Would you please help me figure out the problem?

card.cpp

#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){
  // ... //  
}

card.h

#ifndef CARD_H
#define CARD_H
#include <cctype>
#include <iostream>
#include "conception.h"

class Artifact;
class Spell;


class Card : public Conception
{
  public:
   Card(); 
   Card(const Card &); 
  ~Card();

  protected:
    char* name;
    enum CardType { INSTANT, CREATURE, LAND, ENCHANTMENT, ARTIFACT, PLANESWALKER}; 
    enum CardColor { WHITE, BLUE, BLACK, RED, GREEN, NON };
    CardType type;
    CardColor color; 
    int manaCost;
    char* abilities;
    char* flavorText;
    char* keywords;
    bool inPlay;
    bool tapped;
    bool cursed;
    bool enchanted;
    Artifact* artifact;

    virtual int enchant( Card * );
    virtual int disenchant (Card * );
    virtual int equipArtifact(  Artifact*  );
    virtual Artifact* unequipArtifact(Card * );   
};

// ------------
class Spell: public Card
{
  public:
    Spell(); 
   ~Spell();
   Spell(const Spell &); 

  protected:
    virtual int heal( Spell *&, int );   
    virtual int attack( Spell *& );
    virtual int counter( Spell*& );
    int currToughness;
    int baseToughness;
    int currPower;
    int basePower;
};

class Land: public Card
{
  public:
    Land();
    ~Land();

  protected:
  virtual int generateMana(int);

};

class Forest: public Land
{
  public:
    Forest();
    ~Forest();

  protected:
    int generateMana();

};

class Creature: public Spell
{
  public:
    Creature();
    ~Creature();

  protected:
    bool summoningSick;

};

class Sorcery: public Spell
{
  public:
    Sorcery();
    ~Sorcery();

  protected:

};

#endif

conception.h -- this is an "uber class" from which everything derives

 class Conception{
  public:
    Conception(); 
    ~Conception();
  protected:
    char* classType;
};

conception.cpp

Conception::Conception{
  Conception(){
    classType = new char[11];
    char = "Conception"; 
}

game.cpp -- this is an incomplete class as of this code

#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

game.h

#ifndef GAME_H
#define GAME_H
#include "list.h"

class CardList();

class Battlefield : CardList{
  public:
    Battlefield();
    ~Battlefield();

  protected:
    Card* card;         // make an array
};

class Game : Conception{
  public:
    Game();
    ~Game();

  protected:
    Player** player;    // for multiple players
    Battlefield* root;  // for battlefield
    getPlayerMove();    // ask player what to do
    addToBattlefield();
    removeFromBattlefield();
    sendAttack();

    Battlefield* field;
};

list.cpp

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

list.h

#ifndef LIST_H
#define LIST_H
#include <iostream>
#include "conception.h"

class Node : public Conception {
  public:
    Node() : next(0), prev(0), it(0)
      { it = 0;
        classType = new char[strlen("Node") + 1];
        classType = "Node";
      };
    ~Node(){
      delete it;
      delete next;
      delete prev;
    }

    Node* next;   
    Node* prev; 
    Conception* it;                 // generic object

};

// ----------------------
class LinkedList : public Conception {
  public:
   LinkedList();
   ~LinkedList();
   LinkedList(const LinkedList&);

   friend bool operator== (Conception& thing_1, Conception& thing_2 );

  protected:
   virtual int delete_all(Node*);
   virtual int add( Conception*& );     // 
   virtual Conception* find(Node *&, const Conception*, Conception* );  //   
   virtual int remove( Node *, Node *, Conception* );   // removes  question with keyword   int display_all(node*& );               
   virtual Node* goForward(Node *);
   virtual Node* goBackward(Node *);

   Node* root;
// write copy constrcutor

};

// =============

class CircularLinkedList : public LinkedList {
  public:
   // CircularLinkedList();
   // ~CircularLinkedList();    
   // CircularLinkedList(const CircularLinkedList &);

};

class DoubleLinkedList : public LinkedList {
  public:
//    DoubleLinkedList();
  //  ~DoubleLinkedList();
  //  DoubleLinkedList(const DoubleLinkedList &);

  protected:
};

// END OF LIST Hierarchy


#endif

player.cpp

#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

#ifndef player.h
#define player.h

#include "list.h"

// ============
class CardList() : public LinkedList(){
  public:
    CardList();
    ~CardList();

  protected:
    virtual void findCard(Card&);
    virtual void addCard(Card* );
    virtual void removeCard(Node* root, int id);
    virtual void deleteAll();
    virtual void displayAll();
    virtual void copyCard(const Conception*, Node*&);

    Node* root;
}

// ---------
class Library() : public CardList(){
  public:
    Library();
    ~Library();

  protected:
    Card* card;
    int numCards;
    findCard(Card&);    // get Card and fill empty template
} 
  // -----------

class Deck() : public CardList(){
  public:
    Deck();
    ~Deck();

  protected:
    enum deckColor { WHITE, BLUE, BLACK, RED, GREEN, MIXED };
    char* deckName;


}

// ===============
class Mana(int amount) : public Conception {
  public:
    Mana() : displayTotal(0), classType(0) 
       { displayTotal = 0;
           classType = new char[strlen("Mana") + 1];
           classType = "Mana";
        }; 
  protected: 
    int accrued;    
    void add();
    void remove();
    int displayTotal();

}

inline Mana::add(){   accrued += 1;   }
inline Mana::remove(){  accrued -= 1; }
inline Mana::displayTotal(){  return accrued; }

// ================
class Stats() : public Conception {
  public:
    friend class Player;
    friend class Game;

    Stats() : wins(0), losses(0), winRatio(0) {
             wins = 0; losses = 0; 
             if ( (wins + losses != 0)
               winRatio = wins / (wins + losses);
             else
               winRatio = 0;
           classType = new char[strlen("Stats") + 1];
           classType = "Stats";

            }
  protected:
    int wins;
    int losses;
    float winRatio;
    void int getStats(Stats*& );
}

// ==================
class Player() : public Conception{
  public:
    Player() : wins(0), losses(0), winRatio(0) {
      fname = NULL;
      lname = NULL;
      stats = NULL;
      CardList = NULL;
      classType = new char[strlen("Player") + 1];
      classType = "Player";
    };
    ~Player();
    Player(const Player & obj);

  protected:
  // member variables
    char* fname;
    char* lname;
    Stats stats;            // holds previous game statistics    
    CardList* deck[];       // hold multiple decks that player might use - put ll in this

  private:
  // member functions
    void changeName(const char[], const char[]);
    void shuffleDeck(int);
    void seeStats(Stats*& );
    void displayDeck(int);    
    chooseDeck();
}

// --------------------
class Wizard(Card) : public Player(){
  public:
    Wizard() : { mana = NULL; rootL = NULL; rootH = NULL};
    ~Wizard();

  protected:

    playCard(const Card &);
    removeCard(Card &);
    attackWithCard(Card &);
    enchantWithCard(Card &);
    disenchantWithCard(Card &);
    healWithCard(Card &);
    equipWithCard(Card &);
    Mana* mana[];
    Library* rootL;         // Library  
    Library* rootH;         // Hand
}

#endif
gjnave
  • 479
  • 4
  • 14
  • Including the code is always a good idea, but you need to include the error as well (and make sure it's the error from this version of the code) – JohnL Oct 28 '13 at 19:48
  • three pages worth of redundant errors of this type: player.h:7: error: expected unqualified-id before ')' token player.h:7: error: expected `,' or `;' before ':' token – gjnave Oct 28 '13 at 19:52
  • 1
    So you're saying there's too many errors for you to wade thru? Sorry dude, but you need to boil this down to an [sscce](http://sscce.org/) for your sake and ours - you'll probably figure it out yourself if you minimize the amount of code and the number of files. – kfsone Oct 28 '13 at 19:52
  • First off, look at this: `class Player() : public Conception{`. That's not valid syntax. –  Oct 28 '13 at 19:53
  • Also `#ifndef player.h` 'player.h' is not a legal symbol. Did you mean 'player_h' (remember to change it on the #define line too – kfsone Oct 28 '13 at 19:53
  • That's a syntax error. Syntax error messages can be obscure, but they generally point to the location of the problem. If you get a syntax error message (as opposed to a semantic error like an undeclared identifier or type mismatch), look at the *earliest* flagged line of code. Fix that and recompile. – Keith Thompson Oct 28 '13 at 19:59
  • why am i getting shalacked and taking hits? the point with the errors is not that I dont want to wade through them, but that its 3 pagts of the error having to do with the same stuff. it's for your sake not mine. Being a student I get sick of getting belittled for things I dont understand. If I understood this I wouldnt have to post questions that may seem stupid – gjnave Oct 28 '13 at 20:03
  • 2
    @gjnave Factor that I'm trying not to be rude here: This code is replete not just with syntax errors but bugs, memory leaks, assorted worst practices and lots of logical errors. I think you're in over your head and you need to dial it back and start smaller, rebuild this incrementally. – kfsone Oct 28 '13 at 20:05
  • 1
    @gjnave You're not being shalacked - you're getting a HUGE error report, the next thing you have to do - if you're going to become a programmer - is simplify it so you can isolate the cause or if you want to seek out other programmers to help you. – kfsone Oct 28 '13 at 20:07
  • syntax errors I can understand (and now see) - what worst practices am I committing? I'm asking sincerely so that I can take another whack ath this – gjnave Oct 28 '13 at 20:07
  • @gjnave I'll edit my answer - give me a few minutes. – kfsone Oct 28 '13 at 20:11
  • 1
    updated - tried to cover a bunch of things at once. hope it helps. – kfsone Oct 28 '13 at 20:47

1 Answers1

3

At least one of your problems is that in "player.h" you have

#ifndef player.h
#define player.h

"player.h" is not a legal pre-processor symbol. Did you mean

#ifndef player_h
#define player_h

?

Secondly, conception.cpp doesn't #include anything.

Third, your class definitions are largely invalid.

class Foo()

is not legal, nor is

class Foo() : public class Bar()

What does '()' have to do with a class name? Are you thinking of the constructor?

Then there is this

 char = "Conception"; 

You can't assign a value to a type.

----- Feedback to help you clean up the code -----

. Choose a style

Or - if you are working with someone else's code, take theirs.

But stick with it.

A huge percentage of software defects that make it past initial development are there because they were hard to spot - missing semi-colons, missing {s around compound statements, etc. C.f. "CARD_H" vs "player.h".

. Inconsistency is the mother of most bugs

classType = new char[11];
char = "Conception"; 

You probably mean

classType = new char[11];
classType = "Conception";

but this is a memory leak and a bug waiting to happen. In Card:: you do it more correctly

name = new char[strlen(to_copy.name) +1];         // creating dynamic array
strcpy(to_copy.name, name);

The version you use elsewhere

classType = new ...
classType = "String";

allocates some memory, stores the address in classType. Then it looks up the variable of the compiled char* array "String\0" and stores it's address in classType instead.

When the class goes away, it will try to delete the static string and crash.

If this is a learning exercise and you're trying to learn about memory management, this general approach may be fair enough. But placing ownership of pointers in your classes like this is a sure-fire way to wind up with memory leaks and undefined behavior bugs.

It's best to encapsulate pointers in an RAII-style class (a class which owns the pointer and does the delete when it goes out of scope). Take a look into "std::unique_ptr", "std::shared_ptr" and "std::weak_ptr". For your purposes, "std::string" may help you reduce the number of defects by eliminating a lot of the managerial overhead.

. Try to avoid mixing initializer lists with assignment lists.

It's generally better to use one or the other. You can probably get away with using initializer lists when all of your members can be initialized that way, but if they can't, it may be better to use assignment.

Foo() : m_a(), m_b(), m_c() { m_b = 1; m_c = 2; } // is m_a not having a value a bug or intentional?

. Distinguish member variables from ordinary variables.

You're going to run into bugs where values dissapear on you as a result of shadowing: Shadowing variables

#include <iostream>
int i = 0;
int main() {
    int i = 1;
    for (int i = 0; i < 10; ++i) {
        int i = 2 * i;
        std::cout << i << std::endl;
    }
    return 0;
}

when you don't distinguish your member variables (a lot of people use an "m_" prefix, others use a "_" suffix) this is GOING to happen to you frequently.

. Don't assign numeric values to pointers.

name = 0;

while this compiles, you're setting yourself up for less obvious cases appearing to be numbers and Bad Things Ensuing.

abilities = 0;

No, I'm superman, I have ALL the abilities.

abilities = 42;

Two more correct ways to do this would be

name = NULL; // Traditional C++

or

name = nullptr; // C++11

You've done this in someplaces, again consistency is failing you.

. (minor but it'll bite you in the ass in a few weeks) "it" is generally used to reference an "iterator", you might want to use "data" or "value" or "element".

. avoid making members of classes/objects public.

Your "Node" class looks incredibly buggy (the destructor deletes both prev and next???) and you can't tell, from looking at the class, how the "it" pointer gets set, presumably because that happens elsewhere. Where else do you tamper with the "it", prev and next pointers? Encapsulate.

. 'const' can be your friend (by being a pain in your ass)

if (to_get.class = "Spell"){

This will assign "Spell" to to_get.class, causing a memory leak and other issues, and then succeed -- "Spell" evaluates to a fixed const char* address, which is non-zero, which is therefore true.

(It also doesn't compile because 'class' is a keyword and the actual variable is 'className').

You can prevent this by protecting your actual members and only exposing them thru carefully chosen accessors.

const char* Class() const { return m_className; }

Let me break this one down:

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

The last part means that it can be used on a const 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; }
};

. Lastly: Learn to isolate concepts and algorithms.

A lot of the mistakes/bugs/errors in the code appear to be because you're not 100% with some of the nuances or even details. That's not unreasonable, but you need to find a way to be able to try out the little bits of the language.

Take a little time to learn to roll out micro-programs on something like ideone.com. If you are using Linux, make yourself a "srctest" directory with a "test.cpp" and "test.h" and a Makefile

Makefile

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

srctest.h

#ifndef SRCTEST_SRCTEST_H
#define SRCTEST_SRCTEST_H

// anything I want to test in a .h file here

#endif

srctestextern.cpp

#include "srctest.h"

// Anything you want to test having in a separate source file goes here.

If you're using visual studio, set yourself up something similar.

The idea is to have somewhere you can go and drop in a few lines of code and be comfortable stepping thru what you're trying in a debugger.

Being able to quickly localize problems is a key part of being a successful programmer as opposed to being an employed code monkey.

Community
  • 1
  • 1
kfsone
  • 23,617
  • 2
  • 42
  • 74
  • you're right. I had edited those out before and then lost it during code change and reverting back to old code. *sigh* – gjnave Oct 28 '13 at 20:04
  • @gjnave Consider scrapping your code. It's way easier to put all your thoughts into a document (using kfsone's answer as a reference) than to refactor and wonder why you're getting all these errors. If you test your code step by step it'd be much easier to chew. –  Oct 28 '13 at 20:48
  • C++ has a lot of sharp edges: if C++ was a suit, let's be honest, there'd be a titanium, razor-sharp edge along the crotch, for "flexibility" or C legacy purposes. – kfsone Oct 28 '13 at 20:53
  • Also consider using C++ idioms rather than the C with Classes syndrome you have going on now. I don't see why you would have `new char[strlen(to_copy.name) +1];` instead of using a string or using one of the standard containers instead of rolling your own. It looks like slapped together copy/pasted code. –  Oct 28 '13 at 21:38
  • my prof requires the char* method creating strings. I believe she explained it as an efficiency issue when compared with regularly calling String - the issue having to do with the number of times a copy constructor is called. – gjnave Nov 03 '13 at 22:21
  • Erh - if you are using `const char*` pointers and not copying the strings, she would be correct. But your code was copying the strings. You've done it as `dest = new char[strlen(src) + 1]; strcpy(dest, src);` but lets analyze that. That breaks down to `size_t n = strlen(src); dest = malloc(n + 1); strcpy(dest, src);`. strlen is not free - it iterates the entire string looking for a '\0'. malloc is not free and nor is strcpy - which must again iterate the entire string. – kfsone Nov 04 '13 at 03:45
  • When you construct a std::string from a const char*, it has to do much the same as you're doing, but it KEEPS the length value. Copying a std::string is therefore MUCH cheaper. `dest.m_str = malloc(src.m_size); memcpy(dest.m_str, src.m_str);`. Similarly, the length information is freely available for all other string operations vs having to do strlen() all the time when you use char*s. – kfsone Nov 04 '13 at 03:46
  • So this falls into the "isolate concepts and algorithms". Your code had a number of bugs resulting from your manually repeating some complex string-manipulation operations. This is an *ideal* case for encapsulation and the goal of "Implement once". If std::string is a no-no, then consider making a barebones implementation of your own. – kfsone Nov 04 '13 at 03:53