c++ classes not talking [closed] - c++

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.

Related

Xcode C++ Undeclared Identifier Error

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
}

Creating a Derived Class in C++ [duplicate]

This question already has answers here:
Why have header files and .cpp files? [closed]
(9 answers)
Closed 8 years ago.
So im trying to make a Die class and a LoadedDie class where the Die class is the base and the LoadedDie class is derived. The only difference between the 2 classes is that the roll function in the LoadedDie has a 25% chance of getting the highest number, whereas the Die, has a 1/6 chance. This is my 1st time working with derived class and i seem to have quite a problem trying to complete this task. Can someone explain to me how it works and show me how i would do it with my classes (as im a visual learner and need examples). I know my base class (Die) works as i tested it out before moving to my LoadedDie.
Die.cpp
#include<iostream>
#include <cstdlib>
using namespace std;
class Die{
public:
Die();
Die(int numSide);
virtual int roll() const;
int rollTwoDice(Die d1, Die d2);
int side;
};
Die::Die():side(6){}
Die::Die(int numSide):side(numSide){}
int Die::roll() const{
return rand() % side + 1;
}
int Die::rollTwoDice(Die d1, Die d2){
return d1.roll()+d2.roll();
}
LoadedDie.cpp
#include<iostream>
#include <cstdlib>
#include "Die.cpp"
using namespace std;
class LoadedDie: public Die{
public:
LoadedDie();
LoadedDie(int numSide);
virtual int loadedroll() const;
};
LoadedDie::LoadedDie():side(6){}
LoadedDie::LoadedDie(int numSide):side(numSide){}
int LoadedDie::loadedroll() const{
if ((rand() % 2)+1) = 1){
return side;
}
return (rand() % (side-1)) + 1;
}
int LoadedDie::rollTwoDice(LoadedDie d1, LoadedDie d2){
return d1.roll()+d2.roll();
}
My DieTester.cpp (just a main class to test if the above classes work):
#include "LoadedDie.cpp"
#include<iostream>
#include<time.h>
#include <stdlib.h>
using namespace std;
int main(){
srand(time(NULL));
Die d(6);
LoadedDie dl(6);
cout << d.roll()<<endl;
cout<<"ld " << dl.roll()<<endl;
}
With the classes above, i get this error when i run my DieTester.cpp (if it helps):
In file included from DieTester.cpp:1:
LoadedDie.cpp: In constructor ‘LoadedDie::LoadedDie()’:
LoadedDie.cpp:13: error: class ‘LoadedDie’ does not have any field named ‘side’
LoadedDie.cpp: In constructor ‘LoadedDie::LoadedDie(int)’:
LoadedDie.cpp:15: error: class ‘LoadedDie’ does not have any field named ‘side’
LoadedDie.cpp: In member function ‘virtual int LoadedDie::loadedroll() const’:
LoadedDie.cpp:18: error: expected primary-expression before ‘=’ token
LoadedDie.cpp:18: error: expected ‘;’ before ‘)’ token
I believe that these errors are due to me not deriving the classes properly. Can someone explain to me how this is done?
While the commends about splitting the code into header and code files are all valid (do that NOW) they have nothing to do with the remaining errors and your questions. Lets go through them one by one:
LoadedDie.cpp: In constructor ‘LoadedDie::LoadedDie()’:
LoadedDie.cpp:13: error: class ‘LoadedDie’ does not have any field named ‘side’
LoadedDie indeed has no such member. It is a member of Die. You do not initialize the members of your base class in the derived class like that. Instead you have to call the constructor of the base class like this:
LoadedDie::LoadedDie() : Die() { }
LoadedDie.cpp: In constructor ‘LoadedDie::LoadedDie(int)’:
LoadedDie.cpp:15: error: class ‘LoadedDie’ does not have any field named ‘side’
Same problem again. Same solution:
LoadedDie::LoadedDie(int numSide) : Die(numSide) { }
Note that you can take advantage of default values for arguments and simply write one constructor instead of two:
class Die {
public:
Die(int numSide = 6);
....
}
if ((rand() % 2)+1) = 1){
LoadedDie.cpp: In member function ‘virtual int LoadedDie::loadedroll() const’:
LoadedDie.cpp:18: error: expected primary-expression before ‘=’ token
LoadedDie.cpp:18: error: expected ‘;’ before ‘)’ token
'=' is assignment while you ment equal '=='. You can't assign 1 to (rand() % 2)+1).
It's generally bad form to #include CPP files. But if you want to do it, get rid of the #include "Die.cpp" statement in main.cpp. It's already included in LoadedDie.cpp and so you are including it twice and defining it twice--hence the 'redefinition' error.

Error calling function of a class

I just started writing some code for a class what will be an engine for an analysis, it's simple right now since I'm getting to grips with the stuff I can do with the libraries I import (the bpp ones):
#include <string>
#include <iostream> //to be able to output stuff in the terminal.
#include <Bpp/Seq/Alphabet.all> /* this includes all alphabets in one shot */
#include <Bpp/Seq/Container.all> /* this includes all containers */
#include <Bpp/Seq/Io.all> /* this includes all sequence readers and writers */
class myEngine
{
public:
myEngine();
~myEngine();
void LoadSeq();
};
void myEngine::LoadSeq()
{
bpp::Fasta fasReader;
bpp::AlignedSequenceContainer *sequences = fasReader.readAlignment("tester.fasta", &bpp::AlphabetTools::DNA_ALPHABET);
std::cout << "This container has " << sequences->getNumberOfSequences() << " sequences." << std::endl;
std::cout << "Is that an alignment? " << (bpp::SequenceContainerTools::sequencesHaveTheSameLength(*sequences) ? "yes" : "no") << std::endl;
}
int main()
{
myEngine hi();
hi.LoadSeq();
return 0;
}
I've not defined a constructor or destructor since they take no arguments right now and there aren't any member variable except a member function which returns nothing, just loads a file and prints to cout.
However trying to compile does not work:
rq12edu#env-12bw:~/Desktop/TestingBio++$ make
g++ main.cpp -o mainexec --static -I/local/yrq12edu/local/bpp/dev/include -L/local/yrq12edu/local/bpp/dev/lib -lbpp-seq -lbpp-core
main.cpp: In function 'int main()':
main.cpp:26:5: error: request for member 'LoadSeq' in 'hi', which is of non-class type 'myEngine()'
make: *** [all] Error 1
Maybe I'm being thick but I don't see why it's not letting me execute LoadSeq when I've defined it as a public member of myEngine, why is it erroring when it requests it from the hi instance of myEngine?
Thanks,
Ben W.
This:
myEngine hi();
declares a function, not an object. To declare and default-construct an object, remove the parentheses:
myEngine hi;
In this line:
myEngine hi();
You declare a function hi that returns instance of type myEngine.
Change it either to:
myEngine hi()
or
myEngine hi = myEngine();
This statement
myEngine hi();
is a function declaration with name hi having return type myEngine and no parameters.
Write instead
myEngine hi;
Or
myEngine hi {};
Take into account that you did not define the default constructor and the destructor (at least you did not show their definitions). That the code would ve compiled you couls define it the following way
class myEngine
{
public:
myEngine() = default;
~myEngine() = default;
//...
Or you could remove these declarations (and definitions) and use implicitly defined by the compiler constructor and destructor.

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).

Why C++ compiler (gcc) thinks function is `virtual' field?

I have a the following method definition in my class:
virtual Calc* Compile(
Evaluator* evaluator, ResolvedFunCall* fun_call, string* error);
For some reason, GCC complains that:
error: 'Compile' declared as a 'virtual' field
Any ideas why it would believe Compile to be a field, instead of a method?
I get that error when the first parameter doesn't make sense to it. Check that Evaluator is known as type:
struct A {
virtual void* b(nonsense*, string*);
};
=> error: 'b' declared as a 'virtual' field
struct A {
virtual void* b(string*, nonsense*);
};
=> error: 'nonsense' has not been declared
To find out whether something is a object or function declaration, the compiler sometimes has to scan the whole declaration. Any construct within the declaration that could possibly form a declaration is taken to be a declaration. If not, then any such construct is taken to be an expression. GCC apparently thinks because nonsense is no valid type, it can't be a valid parameter declaration, and thus falls back treating the whole declaration as a field (note that it says in addition error: expected ';' before '(' token ) . Same thing in local scope
int main() {
int a;
// "nonsense * a" not treated as declaration
void f(nonsense*a);
}
=> error: variable or field 'f' declared void
int main() {
// "nonsense * a" treated as parameter declaration
typedef int nonsense;
void f(nonsense*a);
}
=> (compiles successfully)
This happened to me when I declared a virtual function with {} instead of ().
A sample to demonstrate the error:
test.h
class Test{
public:
Test(){}
~Test(){}
//next line is defective, use () instead of {}
virtual int myfunct{int i};//notice brackets here which causes the error
};
test.cpp
#include "test.h"//i omitted include guards for simplicity
int Test::myfunct(int x){
x=5;
return x;
}
main.cpp
#include "test.h"
int main(){
Test test;
return 0;
}