Passing objects by reference in C++ - c++

I am trying to pass an object (of class Stock) by const reference to a function of another class (called Algorithms).
//Algorithms.h
#pragma once
class Algorithms
{
public:
Algorithms(void);
~Algorithms(void);
int Algorithms::doAnalysis(const Stock&);
};
The implementation of doAnalysis is
#include "StdAfx.h"
#include "Algorithms.h"
#include "Stock.h"
#include <vector>
using namespace std;
Algorithms::Algorithms(void)
{
}
Algorithms::~Algorithms(void)
{
}
int Algorithms::doAnalysis(const Stock &S)
{
//Do Something
return 0;
}
The class Stock has the following constructors
public:
Stock(std::string market, std::string symbol);
Stock(std::string market, std::string symbol, std::string start_date, std::string end_date);
I am getting the following error:
Error: declaration is imcompatible with "int Algorithms::doAnalysis(const<error-type> &)" declared at line 8 of Algorithms.h
I understand that the class Stock is not being found. How should I declare the doAnalysis method in Algorithms.h so that it is found? Stock is not a derived class.
Thanks for your help. I am new to C++.

You have to add a forward declaration of the class Stock:
// Forward declaration
class Stock;
class Algorithms
{
public:
Algorithms(void);
~Algorithms(void);
int doAnalysis(const Stock&);
// ^^ <- Remove the Algorithms::
};
You can see here why a forward declaration is necessary in C++.

Put a forward declaration outside your class declaration:
class Stock;
class Algorithms
{
// ...

You could also just add #include "Stock.h" in Algorithms.h file and remove the include from the cpp file. Also you don't need Algorithms:: in the declaration of doAnalysis in Algorithms.h

Related

trouble with accessing a class from a different class

just started to learn c++.I'm trying new things in c++ on thing i wanted to try is to access a class from another class and change its instances and print its instance on screen.
I would like to know 2 things 1)whats wrong with my code 2)where should i declare class declarations (in main file or class definition file?)
here is the error log -
'object::carrier' uses undefined class 'sub'
'cout': is not a member of 'std'
'cout': undeclared identifier
this is what i came up with-
source.h
#include <iostream>
#include <vector>
#include "stuff.h"
int main()
{
object spoon(3);
spoon.get();
}
stuff.cpp
#pragma once
#include <vector>
class object;
class sub;
class object
{
private:
std::vector <sub> thing;
public:
object(int n);
void get() const;
};
class sub
{
private:
int num;
public:
void set_num(int n);
};
stuff.cpp
#include <vector>
#include "stuff.h"
// methods for object
object::object(int n)
{
sub carrier;
carrier.set_num(n);
}
void object::get() const
{
std::cout << carrier.num;
}
// methods for sub
void sub::set_num(int temp_num)
{
num = temp_num;
}
thanks
In your object class, specifically object::get definitions, you use the variable carrier without it being in scope.
When you declare the variable sub carrier in your constructor, it is only accessible in the same scope, that is, inside the constructor. Once your program leaves the scope, the variable carrier is deallocated (deleted).
You must add the variable sub carrier as a member to your class like so:
class object
{
private:
sub carrier
// other stuff
}
Edit:
I so you edited your question.
You must either replace cout with std::cout because cout is part of the c++ standard library. Alternatively, a less verbose option would be to add using namespace std; at the top of every .cpp file. This basically tells the compiler that you can use the namespace std without explicitly saying it. But don't do it for .h files. It's not a good idea.

Getting 'undeclared identifier' when using vector of type class

Having trouble understanding why I'm getting an 'undeclared identifier' error when I've made sure to include the header file that has the declaration of the class I'm making a vector of.
#pragma once
#include <vector>
#include "Member.h"
class Party {
private:
std::vector<Member> members;
public:
Party();
int get_party_size();
void add_member(Member new_member);
Member& get_member(int num);
};
Here's "Member.h"
#pragma once
#include <vector>
#include <string>
#include "Party.h"
class Member
{
private:
int hp;
bool is_stunned;
bool is_alive;
public:
Member();
~Member();
int get_hp();
bool get_is_stunned();
bool get_is_alive();
void take_damage(int amt);
void stun();
virtual void turn(std::vector<Party>& parties, int my_party, int my_member_number);
virtual std::string get_class_name();
};
Pretty new to the language, so sure I'm missing something obvious.
You have circular dependency between Member and Party
Remove the line
virtual void turn(
std::vector<Party>& parties,
int my_party,
int my_member_number);
in Member and remove the #include "Party.h" in Member.h
Instead think along the lines that a Party is just a collection of Members so there is no need for an individual Member to know about the container
So after input from #some-programmer-dude you could also solve it by adding a forward declaration in your Member.h instead of including the Party.h
class Party;
class Member { ... }

Member function definition outside the class

Firstly, I am giving the codes. Then I am explaining the problem I am facing.
main.cpp
#include <iostream>
#include "acc.h"
using namespace std;
class mem;
int main()
{
show();
return 0;
}
acc.h
#ifndef ACC_H
#define ACC_H
#include "acc.cpp"
void show();
class mem{
int a;
public:
void showa();
void seta(int A);
};
#endif
acc.cpp
#include <iostream>
using namespace std;
void mem::showa(){cout<<a<<endl;}
void mem::seta(int A){a = A;}
void show()
{
mem m;
m.seta(22);
string ss;
cin>>ss;
cout<<"MY name is "<<ss<<" ";
m.showa();
}
"mem" class I declared in "acc.h" file already and added that "acc.h" into acc.cpp file also. But when I am calling that class from a function. It can't response. Showing "a" and "mem" not declared. How can I perfectly link that class definition and member functions of that class so that calling member functions of that class from another function can't create any problem?
If you remove the #include "acc.cpp" from the acc.h file it should compile without any errors. I tried and it compiles for me. I am using Visual Studio 2010 for the same.
Other than this, few more comments:
You can use #pragma once in you header file instead of #ifndef/#define macros. The former is more cleaner.
You dont need to forward declare class mem before main() as you are already including acc.h.
the show() can be moved to where main() is defined making the acc.h/acc.cppfiles dedicated for the mem class.
A header file should always be named after the class it is holding i.e. mem.h/mem.cpp in your case. This informs which file contains which class even without opening the file.

expected class-name before '{' token - with header files and cpp files

Like many people asking this question, I am very new to C++ and I can't wrap my head around this error:
Dollar.h:4:31: error: expected class-name before '{' token
class Dollar: public Currency {
These are my files
main.cpp
#include <iostream>
#include "Dollar.h"
using namespace std;
int main() {
Dollar * d = new Dollar();
d->printStatement();
return 0;
}
Currency.cpp
#include <iostream>
#include "Currency.h"
using namespace std;
class Currency {
public:
virtual void printStatement() {
cout << "I am parent";
}
};
Currency.h
#ifndef CURRENCY_H
#define CURRENCY_H
class Currency {
public:
virtual void printStatement();
};
#endif
Dollar.cpp
#include <iostream>
using namespace std;
void printStatement() {
cout << "I am dollar";
}
Dollar.h
#ifndef DOLLAR_H
#ifndef DOLLAR_H
class Dollar : public Currency {
public:
void printStatement();
};
#endif
Thank you so much for your time and any help is much appreciated.
The error says that the name of a class was expected between : public and { here:
class Dollar : public Currency {
^^^^^^^^
Currency is not a name of a class, because you haven't defined such class. Yes, you have defined such class in files Currency.cpp and Currency.h, but not in the file Dollar.h where that error occurs.
Solution: The class Currency has to be defined first before it can be used as a base class. Like so:
// class is defined first
class Currency {
public:
virtual void printStatement();
};
// now Currency is a class and it can be used as a base
class Dollar : public Currency {
public:
void printStatement();
};
Since a class must be defined in all source files where it is used, and the definition must be identical across all source files, it is often useful to define the class in a separate "header" file, such as you have done. In such case you can simply include that header in stead of writing the definition repeatedly in each source file:
#include "Currency.h"
Currency.cpp contains two definitions for the class Currency. Once in the header that is included, and then second time after that. You may not have multiple definitions for the same class in a single source file.
Solution: Remove the class definition from Currency.cpp. Instead only define the member function:
void Currency::printStatement() {
//...
}
Finally, you haven't defined Dollar::printStatement. You've defined printStatement, which is not the same thing.
In my case, I had two classes with same name but in two different namespaces.
So, changing the base class to something different solved the problem.

Failure to compile incomplete types; circular dependencies

Hi am having problems compiling some code, I have a situation where A depends and B depends on A. I have put forward declarations but I keep getting the problems.
In file included from src/MemoWriteContext.h:7:0,
from src/MemoWriteContext.cpp:1:
src/MemoContext.h:29:20: error: field ‘memoWriteContext’ has incomplete type
MemoContext.h
#ifndef MEMOCONTEXT_H_
#define MEMOCONTEXT_H_
#include "sqlite/SqliteDb.h"
#include "Context.h"
#include "MemoWriteContext.h"
#include <string>
#include <memory>
#include <map>
namespace bbs
{
class MemoWriteContext;
class MemoContext : public Context
{
public:
//'structors
MemoContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts,
sqlitecpp::SqliteDb &_sqliteDb);
~MemoContext();
protected:
//when called write the data back to the user
void performAction(const std::string &data, std::shared_ptr<UserAgent> agent);
private:
MemoWriteContext memoWriteContext;
}; //class memocontext
}
#endif // MEMOCONTEXT_H_
MemoWriteContext.h
#ifndef MEMOWRITECONTEXT_H_
#define MEMOWRITECONTEXT_H_
#include "Context.h"
#include "sqlite/SqliteDb.h"
#include "sqlite/PreparedStmt.h"
#include "MemoContext.h"
#include <string>
#include <memory>
#include <map>
namespace bbs
{
class MemoContext; //forward decl
class MemoWriteContext : public Context
{
public:
//'structors
MemoWriteContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts,
MemoContext &_memoContext, sqlitecpp::SqliteDb &_sqliteDb);
~MemoWriteContext();
protected:
//when called write the data back to the user
virtual void performAction(const std::string &data, std::shared_ptr<UserAgent> agent);
virtual void onReceiveUserAgent(std::shared_ptr<UserAgent> agent);
private:
MemoContext &memoContext; //parent;
sqlitecpp::SqliteDb &sqliteDb;
sqlitecpp::PreparedStmt writeMemoStmt;
sqlitecpp::PreparedStmt findAgentIdStmt;
};
enum class MemoWriteState : char
{
USERNAME=0,
MESSAGE,
CONFIRM
};
class MemoWriteAgentData : public ContextAgentData
{
public:
MemoWriteState state;
int userId;
std::string message;
}; //class Memo Write Agent data
}
#endif // MEMOWRITECONTEXT_H_
Full source here.
I think your only problem is that MemoWriteContext.h has #include "MemoContext.h". The context only requires a reference which can use the forward declaration. But if you happen to include MemoWriteContext.h first it will then bring in MemoContext.h before it actually declares class MemoWriteContext. That will then use the forward declaration of class MemoWriteContext and fail. You can even see the ordering in your error message.
Just remove that #include or at least reverse the order of the includes in MemoWriteContext.cpp (since each .h including the other effectively reverses them back).
This:
class MemoWriteContext;
Is a forward declaration. It's an "incomplete type", and therefore cannot be instantiated.
The reason is that a C++ compiler must know the size of any type that has to be instantiated. Incomplete types have no size.
By the way, you can do this:
MemoWriteContext * ptr;
Because you actually declare a pointer, and pointers have a known size.
If you want to avoid dynamic allocations, then you'll have to fully declare the type by including MemoWriteContext.h and removing the forward declaration.