0

So for class we are learning about OOP in C++, and I built my class but every time I try to compile it I get this error message:

    Undefined symbols for architecture x86_64:
  "Player::set_assits(int)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::set_last_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::set_team_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::set_first_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::set_year_of_birth(int)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::set_goals(int)", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::Player()", referenced from:
      _main in playerDataBase-666bbb.o
  "Player::~Player()", referenced from:
      _main in playerDataBase-666bbb.o
ld: symbol(s) not found for architecture x86_64

I can't understand why this happens, I have tried to run this by compiling separate .h, and .cpp files as well as by putting the class, and main function inside of the same .cpp file. Any help would be appreciated as well here is my code.

#include <iostream>
#include <string>

using namespace std;

class Player{


public:
  Player();
  ~Player();

  // accessors and mutators
  void set_first_name(string in_first_name);
  string first_name();
  void set_last_name(string in_last_name);
  string last_name();
  void set_team_name(string in_team_name);
  string team_name();
  void set_year_of_birth(int in_year_of_birth);
  int year_of_birth;
  void set_goals(int in_goals);
  int goals;
  void set_assits(int in_assists);
  int assists;

  //methods
  void display();

private:

  string first_name_;
  string last_name_;
  string team_name_;
  int year_of_birth_;
  int goals_;
  int assits_;


};

void Player::display(){

  cout << first_name_ << last_name_ << endl;
}




int main(){
  Player player;

  player.set_first_name("John");
  player.set_last_name("Tedesco");
  player.set_team_name("Blyth Warriors");
  player.set_year_of_birth(2002);
  player.set_goals(2);
  player.set_assits(7);

  player.display();





}

Thanks for any help and sorry again for messy / poor code.

Thanks,

John

John Tedesco
  • 45
  • 1
  • 7

2 Answers2

2

None of these methods are defined, only declared:

Player();
~Player();

// accessors and mutators
void set_first_name(string in_first_name);
string first_name();
void set_last_name(string in_last_name);
string last_name();
void set_team_name(string in_team_name);
string team_name();
void set_year_of_birth(int in_year_of_birth);
void set_goals(int in_goals);
void set_assits(int in_assists);

You need to provide reasonable definitions for these methods. Right now, you tell the compiler you will provide a definition for each of these methods, and never do. For default constructors, you may use Player() = default;, if you want the compiler to generate a constructor.

For example, to define the first_name property, you may do:

void Player::set_first_name(const string& in_first_name)
{
  first_name_ = in_first_name;
}

const string& first_name() const
{
  return first_name_;
}

Please note I've changed this to take value by constant reference, and return a value by constant reference, rather than by value, for efficiency reasons.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
Alex Huszagh
  • 13,272
  • 3
  • 39
  • 67
  • Thanks for all the help – John Tedesco Mar 05 '18 at 15:54
  • Also quick question because I'm not super familiar with pointers what is the difference between passing it by reference or not – John Tedesco Mar 05 '18 at 16:30
  • @JohnTedesco When you pass by value, the entire contents of the class are copied. When passing by pointer, you pass effectively an integer that "points" to an address in memory. For small data types, like `int`, or `float`, passing by value is actually more efficient than passing by reference. Passing by reference, however, avoids the copy and lets you modify the contents of that reference. In the case above, the `std::string` is a fairly large object that must be copied during your property. Passing it by const reference, or when you become more familiar with C++, by move, is better. – Alex Huszagh Mar 05 '18 at 16:58
  • @JohnTedesco Here's a quick primer on move semantics, FYI: https://stackoverflow.com/questions/3106110/what-are-move-semantics – Alex Huszagh Mar 05 '18 at 16:58
-1

You declared all those fancy methods, e.g:

void set_first_name(string in_first_name);
string first_name();

But you never defined them!

Implement them, and it will work, e.g:

void set_first_name(string in_first_name) {
  first_name_ = in_first_name;
}

string first_name() {
  return first_name_;
}
Daniel Trugman
  • 8,186
  • 20
  • 41