Undefined Symbols Error While Creating Class

May 13, 2020 at 3:32am
Hi! I'm just trying to create a simple class using header a file and I'm encountering an error every time I compile. The error is "Undefined symbols for architecture x84-64" and lists my functions that implement the methods. Here's the code:

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <iomanip>

#include "Account.h"

int main() {
	// set output precision
	std::cout << std::fixed;
	std::cout << std::setprecision(2);

	Account account1;
	
	account1.setName("Bob");
	account1.deposit(100232.33);
	account1.withdraw(500);

	std::cout << "Name: " << account1.getName();
	std::cout << "\nBalance: $" << account1.getBalance() << std::endl;


	return 0;
}


Account.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef _ACCOUNT_H_
#define _ACCOUNT_H_

class Account {
private:
	// attributes
	std::string name;
	double balance;

public:
	void withdraw(double amount);

	void deposit(double amount);

	void setName(std::string sName);

	std::string getName();

	double getBalance();

};

#endif // _Account_H_ 


Account.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "Account.h"

void Account::withdraw(double amount) {

	balance -= amount;
}

void Account::deposit(double amount) {
	
	balance += amount;

}

void Account::setName(std::string sName) {

	name = sName;

}

std::string Account::getName() {

	return name;

}

double Account::getBalance() {

	return balance;
}


Any help is appreciated as I'm just trying to learn. Thanks!
May 13, 2020 at 3:39am
Most apparent problem to me: Account.h does not #include <string> despite using std::string

Edit: fixing that error gives me a program that runs.
Last edited on May 13, 2020 at 3:42am
May 13, 2020 at 3:45am
And where are you including <string>? I'd recommend in your account.h file, before the class declaration.

Once that is fixed you have another rather nasty bug lurking. You are not setting the account balance when creating the account object. That leads to very weird account balance:
Name: Bob
Balance: $-92559631349317830736831783200707727132248687965119994463780864.00

Add a constructor that sets the balance to 0.0.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef _ACCOUNT_H_
#define _ACCOUNT_H_

#include <string>

class Account
{
private:
	std::string name;
	double balance;

public:
	Account() { balance = 0.0; }

	void withdraw(double amount);
	void deposit(double amount);
	void setName(std::string sName);
	std::string getName();
	double getBalance();
};

#endif 
May 13, 2020 at 3:47am
fixing that error gives me a program that runs.

The program may run, but it isn't even close to being correct if the class doesn't set the balance value to 0.0 when it is instantiated.
May 13, 2020 at 3:53am
Thanks for the replies. I've added #include <string> to Account.h and recompiled, yet I still get the error:

Undefined symbols for architecture x86_64:
"Account::getBalance()", referenced from:
_main in class-25f06d.o
"Account::deposit(double)", referenced from:
_main in class-25f06d.o
"Account::getName()", referenced from:
_main in class-25f06d.o
"Account::setName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in class-25f06d.o
"Account::withdraw(double)", referenced from:
_main in class-25f06d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation

Thoughts?
Last edited on May 13, 2020 at 3:54am
May 13, 2020 at 3:56am
And where are you including <string>? I'd recommend in your account.h file, before the class declaration.

That is indeed where I chose to include.


it isn't even close to being correct

Thank you for correcting this; I hadn't noticed because my program gave the desired output, presumably due to a compiler-specific implementation (I use g++).
May 13, 2020 at 3:57am
The balance data member can be initialized without having a constructor (C++11 or higher):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef _ACCOUNT_H_
#define _ACCOUNT_H_

#include <string>

class Account
{
private:
	std::string name;
	double balance = 0.0;

public:
	void withdraw(double amount);
	void deposit(double amount);
	void setName(std::string sName);
	std::string getName();
	double getBalance();
};

#endif 
May 13, 2020 at 4:04am
Your next round of errors are linker errors. Now I don't use g++ for my compiler so this is a bit of spit-balling.

Your compile/link command(s) are likely not including account.cpp. You are compiling/linking just main.cpp (+ account.h)
May 13, 2020 at 4:08am
I have a feeling that this is probably the most likely scenario. I just don't know how to get all three files compiled together. Thanks!
May 13, 2020 at 4:10am
I hadn't noticed because my program gave the desired output, presumably due to a compiler-specific implementation

^^^ This is the main reason why I use more than one compiler/IDE. So little things like differing implementation details make spotting logic/run-time errors easier.
May 13, 2020 at 4:17am
How are you compiling/linking your code? Using an IDE? command-line?
May 13, 2020 at 4:21am
I'm just writing using Sublime and compiling with g++. So I'm not sure why the other commenter was able to get the program to run.
Last edited on May 13, 2020 at 4:21am
May 13, 2020 at 4:24am
I don't have a clue about Sublime, how to include files into the build process.

Now, if you were using Code::Blocks, that I could answer. If MS Visual Studio, I'm your huckleberry! ;)
May 13, 2020 at 4:24am
For g++ (assuming the command line), just list both .cpp files as arguments:

g++ Account.cpp main.cpp
May 13, 2020 at 4:26am
^^That did it! Program compiles and runs as expected now! Thanks, everyone!
Topic archived. No new replies allowed.