Xcode C++ Undeclared Identifier Error - c++

I have created a class in a header file and have listed a int rsvdtickets in the private section of the class. When trying to use this member in a function in the same header file (I am trying to add ticket prices so I am wanting to save the total under this int rsvdtickets), the compiler throws an undeclared identifier error.
I've made sure the spelling is all correct, but I am not sure how to fix this problem.
#include <iostream>
#include <math.h>
class tickets
{
public:
void getheldtickets();
void computeseats();
void availabetickets();
private:
int rsvdtickets;
int availtickets;
};
void getheldtickets()
{
int seasontkt;
int corptkt;
std::cout << "How many season ticket holders?";
std::cin >> seasontkt;
std::cout << "How many reserved corporate ticket holders?";
std::cin >> corptkt;
rsvdtickets = seasontkt + corptkt;
}

The problem is that when you have:
void getheldtickets()
{
// ..
rsvdtickets = seasontkt + corptkt;
}
You're not defining tickets::getheldtickets, you're actually declaring and defining an entirely unrelated free function called getheldtickets. That function is unrelated to the class tickets, and thus has no access to the tickets members - and so rsvdtickets is an declared identifier.
The correct way to define a class method external to the class is:
void tickets::getheldtickets()
// ^^^^^^^^^
{
// everything as before
}

Related

C++ - undefined reference to 'Class::variable'

I keep getting error: undefined reference to 'Company::budget'.
My method is set so as to take the value of company's (any created) budget and subtract Employees' salary from it. I keep getting this problem. Tried both pointers and let's say "normal calling". Ok, there's the code snippet: (rest of it works)
company.h
#include <iostream>
#include <cstdlib>
#include <list>
#include <vector>
#include "employee.h"
using namespace std;
class Company
{
public:
Company* comp;
void hire(Employee& emp, float putSalary);
void fire(Employee& emp);
void endOfMonth(Company& comp);
Company(float);
// static float moneyamount;
private:
static float budget;
vector <Employee>* Employees;
};
company.cpp
void Company::endOfMonth(Company& comp)
{
for (iterat=0; iterat < Employees->size() ; iterat++)
{
cout << (*Employees)[iterat].fullName << endl;
cout << (*Employees)[iterat].getSalary() << endl;
comp.budget = comp.budget - (*Employees)[iterat].getSalary();
}
}
You are missing the definition of the static class data member. Add the following line to the file company.cpp:
float Company::budget;
Static class members variables are static over all instances of a class. So if you have two instances of one class, they share the static variable. Also, these variables are also valid even when there is no instance of the class. So, static member functions may use static member variables. That is the reason why they must defined somewhere outside the class in the object file.
You define it and reserve the necessary space for it in memory at the top level of you .cpp file:
float Company::budget;

Program keeps on giving such LNK errors

header.h
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
//vector <Account> bankAccounts; this is taken out.
extern vector <Account> bankAccounts; //edited
struct Account {
int accountNumber;
string lastName;
string firstName;
double accountbalance;
};
void menu(int*);
void makeAccount(vector <Account>&);
cpp
#include "Header.h"
void menu(int*);
void makeAccount(vector <Account>&);
vector <Account> bankAccounts; //edited
int main() {
int input = 0;
int *inputPtr = &input;
menu(inputPtr);
switch (input) {
case 1:
makeAccount(bankAccounts);
}
}
another cpp
#include "Header.h"
vector <Account> bankAccounts; edited;
void menu(int *inputPtr) {
int select = 0;
cout << "Welcome to MadeUp Banking. Select options below: \n";
cout << "\t 1. Make new account. \n";
cout << "\t 2. Display to an account. \n";
cout << "\t 3. Deposit to an account. \n";
cout << "\t 4. Withdraw from an account. \n";
cout << "\t 5. Print account. \n";
cout << "\t 6. Delete an account. \n";
cout << "\t 7. Quit. \n";
cout << "Selection: ";
cin >> select;
*inputPtr = select;
}
void makeAccount(vector <Account> bankAccounts) {
//edited vector <Account> bankAccounts within makeAccount()
return;
}
When program is ran, the error gives:
main_file.obj : error LNK2005: "class std::vector > bankAccounts" (?bankAccounts##3V?$vector#UAccount##V?$allocator#UAccount###std###std##A) already defined in function_file.obj
1>main_file.obj : error LNK2019: unresolved external symbol "void __cdecl makeAccount(class std::vector > &)" (?makeAccount##YAXAAV?$vector#UAccount##V?$allocator#UAccount###std###std###Z) referenced in function _main
How do I go about fixing this error?
Sorry I'm a rookie coder, if more details are needed, then please tell me and I will edit accordingly. Thank you for the help in advance.
1. bankAccounts already defined in function_file.obj.
You should define bankAccounts in your cpp file. Because if you define it in header file, when you include your header in multiple cpp files, there would be multiple definition of backAccounts.
If you needs it in multiple cpp files, use extern to declare(not define) it in your header file:
extern vector <Account> bankAccounts;
And in one of your cpp file, define it as:
vector <Account> bankAccounts;
2. unresolved external symbol void makeAccount()
Definition of makeAccount() should be like:
void makeAccount(vector <Account>&)
{
// do something
}
While you are defining it as void makeAccount(vector<Account>). Please notice the difference. In your declaration, parameter is reference to a vector, while in your definition, parameter is vector object.
The error message of the first error, which can be abridged to:
main_file.obj : error LNK2005: std::vector<Account> bankAccounts already defined in function_file.obj
The reason for this error is that included files are copy-pasted in place of #include. That way, the std::vector<Account> bankAccounts is defined in both files (and they are, completely separate objects!), so the linker complains because of the multiple-definitions.
To solve this, in the header file, declare the global variable as extern std::vector<Account> bankAccounts, and then define it, in one of the .cpp files as std::vector<Account> bankAccounts. extern, only declares that there will be such a variable defined, at some point, and since you will be defining a global variable once, the linker won't see multiple definitions of said variable.
The second error is just like it sounds: you declared (and tried to call a function with signature void makeAccount(vector <Account>&);, however, you defined a function with signature void makeAccount();, leaving the function void makeAccount(vector <Account>&); undefined. Fix the definition of a function to include the parameter, present in its declarations:
void makeAccount(vector <Account>&) {
return;
}
Unrelated to your issues, but I felt that I should mention several more things:
Don't use using namespace std;, especially in the header files, it is considered a bad practice.
How is your code even reaching the linker stage? It shouldn't even compile, because Account is declared after the void makeAccount(vector <Account>&);, and at the point of such function declaration - struct Account is not known to the compiler.

How to make a variable available to multiple .cpp files using a class?

This question has derived from this one.
I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.
So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:
#include <iostream>
using namespace std;
int entero = 10;
void function()
{
cout<<entero<<endl;
//action1...;
}
void separated_function()
{
cout<<entero<<endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:
In the previous question #NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).
And, as far I can understand, in the answer provided by #PaulH., he is describing how to make variables avaliable by making them global.
This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).
But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.
I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.
You need to give the parameter as a reference if you want the same comportement as a global variable
#include <iostream>
using namespace std;
// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}
void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}
int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable
// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
output:
10
11
12
Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.
You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.
Lets take a simple example, with one header file and two source files.
First the header file, e.g. myheader.h:
#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice
// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}
int get_value() const
{
return value_;
}
void set_value(const int val)
{
value_ = val;
}
private:
int value_;
};
// Declare a function prototype
void bar(my_class& v);
}
#endif // MYHEADER_H
The above header file defines a namespace foo and in the namespace a class my_class and a function bar.
(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)
Then the first source file, e.g. main.cpp:
#include <iostream>
#include "myheader.h" // Include our own header file
int main()
{
using namespace foo;
my_class my_object(123); // Create an instance of the class
bar(my_object); // Call the function
std::cout << "In main(), value is " << my_object.get_value() << '\n';
// All done
}
And finally the second source file, e.g. bar.cpp:
#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}
Put all three files in the same project, and build. You should now get an executable program that outputs
In foo::bar(), value is 123
In main(), value is 456
I prefer to provide a functional interface to global data.
.h file:
extern int get_entero();
extern void set_entero(int v);
.cpp file:
static int entero = 10;
int get_entero()
{
return entero;
}
void set_entero(int v)
{
entero = v;
}
Then, everywhere else, use those functions.
#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}
void separated_function()
{
cout << get_entero() << endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:
const int ENTERO = 10;
If you are using multiple cpp files, also consider using a header file for your structures and function declarations.
If you are planning on modifying the variable, just pass it around in function parameters.

c++ classes not talking [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
i am using gvim to do c++ for a class (since we are told we have to do it in linux, and the class is taught using c++). i have had java classes before, but this teacher isn't really telling us how to do things in c++ or linux since he states it's another class that just uses c++.
the problem i am having for my homework is that we have to create some classes and have them get info to each other, but i keep getting errors whenever i try to compile. (i can't seem to figure out how to get them to talk to each other and use functions/variables from one another.)
ex:
class a {
string user;
public: string user2;
public: vector<string> friendList;
public: void userName()
{
cout output
cin >> user;
}
public: void addFriend()
{
cout output
cin >> user2;
friendList.push_back(user2);
}
public: string getName()
{
return user;
}
};
(have tried this second class 2 ways and neither work)
way1--->
class b {
string message, username;
a User;
public: void postMessage()
{
cout ____
getline(cin, message);
username = User.getName();
}
};
or this way---->
class b: public a {
string message, username;
a User;
public: void postMessage()
{
cout ____
getline(cin, message);
username = User.getName();
}
};
(or had the function like this:)
public: void postMessage()
{
cout ____
getline(cin, message);
username = user2;
}
};
the classes don't seem to talk to each other either way, and i'm not sure how to get them to since these ways don't work and that's what was in the book/what i found on the internet so far.
so i guess my question is how can i get a to talk to b so b can use functions or variables from a? need to know so the classes can talk to eachother and also so i can get the main function to also call each class (each class is in a separate .cpp file btw).
EDIT:
(the classes are in different files)
i made a script for the terminal for the errors:
Script started on Sun 29 Sep 2013 02:27:42 PM CDT
]0;darksithis002#darkmist002-VirtualBox: ~/lab1darksithis002#darkmist002-VirtualBox:~/lab1$ g++ -c homepg.cpp
homepg.cpp:14:26: error: expected class-name before ‘,’ token
homepg.cpp:15:1: error: expected class-name before ‘{’ token
homepg.cpp:18:24: error: ‘user’ was not declared in this scope
homepg.cpp:18:24: error: ISO C++ forbids initialization of member ‘userName1’ [-fpermissive]
homepg.cpp:18:24: error: making ‘userName1’ static [-fpermissive]
homepg.cpp:18:24: error: invalid in-class initialization of static data member of non-integral type ‘std::string {aka std::basic_string<char>}’
homepg.cpp:19:19: error: ISO C++ forbids initialization of member ‘counter’ [-fpermissive]
homepg.cpp:19:19: error: making ‘counter’ static [-fpermissive]
homepg.cpp:19:19: error: ISO C++ forbids in-class initialization of non-const static member ‘counter’
homepg.cpp:20:30: error: ‘friendList’ was not declared in this scope
homepg.cpp:20:30: error: ISO C++ forbids initialization of member ‘friends’ [-fpermissive]
homepg.cpp:20:30: error: making ‘friends’ static [-fpermissive]
homepg.cpp:20:30: error: invalid in-class initialization of static data member of non-integral type ‘std::vector<std::basic_string<char> >’
homepg.cpp:22:5: error: ‘cout’ does not name a type
homepg.cpp:23:5: error: ‘cout’ does not name a type
homepg.cpp:24:5: error: ‘cout’ does not name a type
homepg.cpp:29:26: error: ISO C++ forbids declaration of ‘displayHome’ with no type [-fpermissive]
homepg.cpp: In member function ‘int homepg::displayHome()’:
homepg.cpp:31:12: error: ‘messageBuff’ was not declared in this scope
homepg.cpp:45:6: error: ‘nextbrac’ was not declared in this scope
homepg.cpp:53:18: error: ‘userName’ was not declared in this scope
homepg.cpp:64:28: error: ‘friends’ was not declared in this scope
homepg.cpp:85:6: error: ‘count’ was not declared in this scope
]0;darksithis002#darkmist002-VirtualBox: ~/lab1darksithis002#darkmist002-VirtualBox:~/lab1$ g++ -c messageBuffer.cpp
messageBuffer.cpp: In member function ‘void messageBuffer::postMessage()’:
messageBuffer.cpp:26:13: error: ‘user’ was not declared in this scope
messageBuffer.cpp: In member function ‘void messageBuffer::tweetMessage()’:
messageBuffer.cpp:45:17: error: ‘user’ was not declared in this scope
]0;darksithis002#darkmist002-VirtualBox: ~/lab1darksithis002#darkmist002-VirtualBox:~/lab1$ exit
exit
Script done on Sun 29 Sep 2013 02:29:16 PM CDT
as a test, i put 2 of my classes together, one that compiled fine on it's own, and one that needed a function/variable from the other class, and tried to compile, and they compiled fine as
class a {
*functions and variables for a* }
class b {
a A;
*functions for b* }
class b in this example just doesn't work if i have it in a separate file in the same directory trying to call a, it gives me the errors i got in the script i made.
EDIT2: i'm also getting an error in the test file if i put in a main function and have it call functions from class a and b. (i know this error is from not declaring the functions, but if i try to declare them in their class, they give me another error which is: type::functionname cannot be overloaded, but if i take out the declaration both a and b compile fine and b can use a's functions, so why is it that they can fine without function declartions but a main function can't? and where do i put the declarations for the functions if i can't have them in the classes since it says it can't overload them?)
First of all - you only need to write "public:" once and then everything after that is public (until you write "private:" or similar).
Second - your firt "class b" seems to be the correct one.
Third - are both classes written in the same file? Or in different files? If in differebt files - did you include the file for a in the file for b? Are they .h files or .cc files?
Edit: here's how it should be, lets say a single file for now:
one file, main.cc:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class a {
string user;
public:
string user2;
vector<string> friendList;
void userName()
{
cout <<"blah blah"<<endl;
cin >> user;
}
void addFriend()
{
cout <<"blah blah"<<endl;
cin >> user2;
friendList.push_back(user2);
}
string getName()
{
return user;
}
};
class b {
string message, username;
a User;
public:
void postMessage()
{
cout <<"blah blah"<<endl;
getline(cin, message);
username = User.getName();
}
};
int main(){
b test;
test.postMessage();
}
There are many issues with your classes obviously - but this should compile at least.
Here are some hints to get you moving!
Define one class per file, and wrap header files (*.h) in include guards.
File a.h
#ifndef A_H
#define A_H
#include <string>
#include <vector>
#include <iostream>
class a // This class needs a better name!
{
private: // Class members are private by default but it's best to be explicit
std::string user; // When using classes from the C++ Standard Library in a
// header file, specify the `std` namespace explicitly
public: // Everything below here is public
std::vector<std::string> friendList;
void userName()
{
std::cout << "User name: "; // Note the use of `std::` here otherwise you'll see
// ‘cout’ does not name a type
std::cin >> user;
}
void addFriend()
{
std::cout << "Add friend: ";
std::string user2;
std::cin >> user2;
friendList.push_back(user2);
}
std::string getName()
{
return user;
}
};
#endif
File b.h
#ifndef B_H
#define B_H
#include <string>
#include <iostream>
#include "a.h" // Tell the pre-processor to include the entire contents of `a.h`,
// so that the code below knows what `class a` is.
class b
{
private:
std::string message, username;
a User;
public:
void postMessage()
{
std::cout << "Post Message: ";
std::getline(std::cin, message);
username = User.getName();
}
};
#endif
File main.cpp
This is the only file you need to compile, since it includes b.h (and a.h within that).
#include "b.h"
int main()
{
b my_b;
my_b.postMessage();
}
In the code above, like "Way 1", class b contains an instance of class a.
If you wished class b to extend class a, like "Way 2", you would use something like this:
class b: public a
{
// [...]
public:
void postMessage()
{
std::cout << "Post Message: ";
std::getline(std::cin, message);
username = getName();
}
};
To compile
Either use the terminal:
g++ -I/usr/local/include -Wall -Wextra -pedantic main.cpp -o main
Or use a Vim Script like SingleCompile.

State Machines, Sub-Classes, and Function Pointers

I'm having trouble implementing a state machine for class. I keep getting the errors:
state.cpp:5: error: have0 was not declared in this scope
state.cpp:10: error: redefinition of State* Have0State::process(std::string)
state.h:18: error: virtual State* Have0State::process(std::string) previously defined here
I'm trying to get the Have0State to work before I continue onto the rest of the machine, hence the sparse code.
state.h:
#ifndef STATE_H
#define STATE_H
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
class State{
public:
State(){};
virtual State* process(std::string input) = 0;
};
class Have0State: public State {
public:
Have0State():State(){};
virtual State* process(std::string input);
}have0;
#endif
state.cpp:
#include "state.h"
using namespace std;
State *currentState = &have0;
State* Have0State::process(string input){
if(input == "quarter"){
cout << "cool" << endl;
}
return &have0;
}
int main(int argc, char** argv) {
string input;
//get input
cin >> input;
while (input != "exit") {
currentState = currentState->process(input);
//get input
cin >> input;
}
return 0;
};
I've tried defining the process function as Have0State::State::process(string input) but that didn't work either. Any clarification on how function pointers are supposed to work, especially in the context of subclass member functions, I would greatly appreciate it.
EDIT: Also, what exactly is the have0 declaration at the end of the Have0State class declaration in the state.h file? It doesn't have an explicitly stated type; is it implied that it is of type Have0State??
There aren't any function pointers in your example. Also, like Marciej, I am able to compile (and run) this code.
But, since you asked, the 'have0' declaration simply declares an instance of the class. A class definition can be followed by 0 or more of these declarations (as well as initializers):
class Thing {...} one, another, many[3] = { Thing(1), Thing(2), Thing(3) };
the same as for any other type:
int counter = 0, flag = 0x80, limit = 500;
The possibility of this optional declarator list is why class, struct, union, and enum definitions must be followed with a semi-colon (to terminate the list).
But, as Karthik said, defining a variable in a header will cause "duplicate definition" errors at link time, if the header is included in more than one .cpp file. IMO it's fine though to use this technique to define and declare private objects in a .cpp file (rather than a .h file).