Calling a method from a constructor in another class c++ - c++

I need to call a method from one class in the constructor of another class. I am not sure how to do this without getting a "was not declared in this scope" error. Note I am just learning C++.
See the comments in symboltable.cpp for what I am trying to accomplish here. I am not looking for anyone to do it for me. I could use an example or pointed in the right direction so I can figure this out.
symboltable.h code:
class SymbolTable
{
public:
SymbolTable() {}
void insert(string variable, double value);
void insert(string variable); // added for additional insert method
double lookUp(string variable) const;
void init(); // Added as mentioned in the conference area.
private:
struct Symbol
{
Symbol(string variable, double value)
{
this->variable = variable;
this->value = value;
}
string variable;
double value;
};
vector<Symbol> elements;
};
symboltable.cpp code:
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include "symboltable.h"
/* Implementing the "unreferenced variable" warning.
* Modify the symbol table by adding another insert method
* that supplies only the variable name.
* This method should be called when the variable name
* is encountered while building the arithmetic expression tree.
* It would be called in the constructor of the Variable class.
* The existing insert method, which is called when an assignment is encountered,
* would first check to see whether it is already in the symbol table.
* If it is not, then it is unreferenced.
*/
void SymbolTable::insert(string variable, double value)
{
/* This existing insert method, which is called when an assignment is encountered,
* first needs to check to see whether it is already in the symbol table.
* If it is not, then it is unreferenced.
* */
//Need to check if variable is in the expression need to find out how the expression is stored!
if (find(elements.begin(), elements.end(), variable)) {
const Symbol& symbol = Symbol(variable, value);
elements.push_back(symbol);
} else
throw string("Error: Test for output");
}
/* Adding another insert method that supplies only the variable name.
* This method should be called when the variable name is encountered
* while building the arithmetic expression tree.
* It should be called in the constructor of the Variable class.
*/
void SymbolTable::insert(string variable)
{
const Symbol& symbol = Symbol(variable, symbolTable.lookUp(variable));
elements.push_back(symbol);
}
double SymbolTable::lookUp(string variable) const
{
for (int i = 0; i < elements.size(); i++)
if (elements[i].variable == variable)
return elements[i].value;
else
throw "Error: Uninitialized Variable " + variable;
return -1;
}
void SymbolTable::init() {
elements.clear(); // Clears the map, removes all elements.
}
variable.h code:
class Variable: public Operand
{
public:
Variable(string name) //constructor
{
// how do i call symbolTable.insert(name); here
// without getting 'symboleTable' was not declared in this scope error
this->name = name;
}
double evaluate();
private:
string name;
};
variable.cpp code:
#include <string>
#include <strstream>
#include <vector>
using namespace std;
#include "expression.h"
#include "operand.h"
#include "variable.h"
#include "symboltable.h"
extern SymbolTable symbolTable;
double Variable::evaluate() {
return symbolTable.lookUp(name);
}

There are two solutions:
You use a global variable - like your Variable::evaluate() example. You can of course add your Variable::Variable() as a function in "variable.cpp" instead of the header. Or you can just put a extern SymbolTable symbolTable to the file "variable.h".
You pass in a reference to symbolTable into the constructor (and perhaps store that inside the Variable object - that way, symbolTable doesn't need to be a global variable at all.
By the way, it's generally considered bad style to add using namespace std before header files.

extern SymbolTable symbolTable; needs to go into the header file that is included by everyone who needs symbolTable. Then, in variable.cpp, you need to have SymbolTable symbolTable;

You need to instantiate the second class, either within the constructor, which will make it and its members available only within the constructor of the first class, or in the global namespace. For example:
MyFooClass CFoo;
MyBarClass CBar;
MyFooClass::MyFooClass()
{
CBar = new MyBarClass();
CBar.BarClassMemberFunction();
}

Related

initializing a static (non-constant) variable of a class.

I have TestMethods.h
#pragma once
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>
class TestMethods
{
private:
static int nextNodeID;
// I tried the following line instead ...it says the in-class initializer must be constant ... but this is not a constant...it needs to increment.
//static int nextNodeID = 0;
int nodeID;
std::string fnPFRfile; // Name of location data file for this node.
public:
TestMethods();
~TestMethods();
int currentNodeID();
};
// Initialize the nextNodeID
int TestMethods::nextNodeID = 0;
// I tried this down here ... it says the variable is multiply defined.
I have TestMethods.cpp
#include "stdafx.h"
#include "TestMethods.h"
TestMethods::TestMethods()
{
nodeID = nextNodeID;
++nextNodeID;
}
TestMethods::~TestMethods()
{
}
int TestMethods::currentNodeID()
{
return nextNodeID;
}
I've looked at this example here: Unique id of class instance
It looks almost identical to mine. I tried both the top solutions. Neither works for me. Obviously I'm missing something. Can anyone point out what it is?
You need to move the definition of TestMethods::nextNodeID into the cpp file. If you have it in the header file then every file that includes the header will get it defined in them leading to multiple defenitions.
If you have C++17 support you can use the inline keyword to declare the static variable in the class like
class ExampleClass {
private:
inline static int counter = 0;
public:
ExampleClass() {
++counter;
}
};

Pass created object as argument, from inside that object, C++

I am facing the following problem. I have the following classes, Room and Reservation . For Reservation class there is a function (void Reservation :: rsrvRoomAssignment(Room* r)) that assigns the Room* rsrvRoom member of Reservation class, to a Room object. I want though to call this class from inside the Room object but i have no clue on how to achieve that properly passing as argument the created object that runs the code.
The code describes the above:
Reservation.h
class Room;
class Reservation {
public:
static int rsrvCode;
string rsrvName;
unsigned int rsrvDate;
unsigned int rsrvNights;
unsigned int rsrvPersons;
Room* rsrvRoom; // Room assigned to reservation.
Reservation();
~Reservation();
void rsrvRoomAssignment(Room*);
};
Reservation.cpp
#include <iostream>
#include "Reservation.h"
using namespace std;
/*
Constructor & Destructor
*/
void Reservation :: rsrvRoomAssignment(Room* r){
rsrvRoom=r;
}
Room.h
#include "Reservation.h"
class Room {
public:
static unsigned int roomNumber;
unsigned int roomCapacity;
Reservation* roomAvailability[30];
double roomPrice;
Room();
~Room();
bool roomReservationAdd(Reservation*);
};
Room.cpp
#include <iostream>
#include <string>
#include "Room.h"
using namespace std;
/*
Constructor & destructor
*/
bool Room::roomReservationAdd(Reservation* r){
/* some statement that returns flase */
r->rsrvRoomAssignment(/* & of created object */); // This is the problem i described.
return 1;
}
I am pretty new to OOP so there might be some more logical errors on the above snipsets, so don't be harsh :) .
Thanks for any kind of help!
When inside a class method, this indicates the instance of the object calling it. In your case, when a room instance X calls X.roomReservationAdd(r),
this points to the room instance X.
Hence, you can simply call r->rsrvRoomAssignment(this);

Returning array of character error in c++?

I have these two files table.cpp and table.h in my program code apart from the main.cpp. The files are described as below
table.cpp
#include <iostream>
#include "table.h"
using namespace std;
// accessor function for Name
char* PeriodicTable::Name()
{
return Name;
}
// accessor function for Symbol
char* PeriodicTable::Symbol()
{
return Symbol;
}
table.h
#ifndef TABLE_H
#define TABLE_H
class PeriodicTable
{
char Name[15], Symbol[3], GroupName[20], Block, State[25], Colour[15], Classification[20];
int GroupNo, AtomicNo, PeriodNo;
float Weight;
public:
char* Name();
char* Symbol();
};
#endif
but the problem is that the IntelliSense(since I am using Visual C++ Express 2010) shows a red curved underline below the name and symbol in the accessor function in table.cpp. I can't understand why???
Your member functions and member variables have the same name. This is not possible in C++. That's why various conventions exist for naming member variables, e.g. m_name, name_ etc. (NB: When dealing with underscores in identifiers make sure you don't use a reserved name by accident.)
You might wonder why and how that could possibly go wrong. In your example there clearly is no way to invoke operator() on char[15], but the problem is that the compiler only knows that after performing semantic analysis. There could also be cases where it is impossible to disambiguate. For example:
struct Func {
void operator()() { };
};
struct C {
Func f;
void f() {}
};
int main() {
C c;
c.f(); // which one?
}

No Matching Function Call

I'm new to C++ and trying to code a HashTable data structure.
I've written it to be generic using templates, and I've included a HashEntry object to use in it to allow for easy quadratic probing for collisions.
The code I have is:
(in a .C file that #include's the below class definition .H file):
HashEntry::HashEntry()
{
this->isActive = false;
}
And the associated .H file with the class definitions is:
#include <iostream>
#include <string>
#include "Entry.C"
using namespace std;
#define Default_Size 50000
class HashEntry;
template <class T> class HashTable
{
private:
int size;
int occupied;
T array[Default_Size];
public:
HashTable();
int Size();
void Add(T t);
void DebugAdd(T t, int index);
T* Get(string index);
/* How do I declare the existence of HashEntry BEFORE here? */
int FindNextOpen(HashEntry he); // Only works for hash_entry objects!
int Hash(string str);
void Rehash();
};
class HashEntry
{
private:
Entry e;
bool isActive;
public:
HashEntry();
HashEntry(Entry e);
bool IsActive();
Entry GetEntry();
};
Whenever I try and compile everything, I get the error for the HashEntry constructor above:
"no matching function for call to Entry::Entry()" ... "candidates are.....".
I have no idea what it means -- when I try to include a default Entry() constructor (my first interpretation), it throws more errors.
Thanks for the help!
UPDATE -- ENTRY.C:
#include "Entry.H"
/* ***Entry Methods*** */
/*
* Overloaded Entry obejct constructor that provides a string value.
*/
Entry::Entry(string s)
{
this->value = s;
this->count = 0;
}
/*
* Returns the number of times this Entry has been accessed/
* found.
*/
int Entry::Count()
{ return this->count; }
/*
* Returns the string value stored in the Entry object.
*/
string Entry::Value()
{ return this->value; }
And the associated .H file with the class definitions is:
#include <iostream>
#include <string>
#include "Entry.C"
Whoa! Never, ever #include a source file in a header.
Your Entry.C should not exist. Instead define the constructor in your header, inside the class definition:
class HashEntry
{
private:
Entry e;
bool isActive;
public:
HashEntry() : isActive(true) {}
...
}
One thing that you haven't shown us is the definition of the class Entry. That is one of the sources of your problem. It's a bit hard to pin down your problem when you didn't show us the very thing that is causing it.
I found the problem.
The error message says there is not matching function call for "Entry::Entry()". Because in no case was I actually creating Entry objects I had no idea what it meant.
I tried adding an explicit default constructor for class Entry and it resolved.
Thanks for the help everyone!

error: expected constructor, destructor, or type conversion before '(' token

include/TestBullet.h:12: error: expected constructor, destructor, or type conver
sion before '(' token
I hate C++ error messages... lol ^^
Basically, I'm following what was written in this post to try to create a factory class for bullets so they can be instantiated from a string, which will be parsed from an xml file, because I don't want to have a function with a switch for all of the classes because that looks ugly.
Here is my TestBullet.h:
#pragma once
#include "Bullet.h"
#include "BulletFactory.h"
class TestBullet : public Bullet {
public:
void init(BulletData& bulletData);
void update();
};
REGISTER_BULLET(TestBullet); <-- line 12
And my BulletFactory.h:
#pragma once
#include <string>
#include <map>
#include "Bullet.h"
#define REGISTER_BULLET(NAME) BulletFactory::reg<NAME>(#NAME)
#define REGISTER_BULLET_ALT(NAME, CLASS) BulletFactory::reg<CLASS>(NAME)
template<typename T> Bullet * create() { return new T; }
struct BulletFactory {
typedef std::map<std::string, Bullet*(*)()> bulletMapType;
static bulletMapType map;
static Bullet * createInstance(char* s) {
std::string str(s);
bulletMapType::iterator it = map.find(str);
if(it == map.end())
return 0;
return it->second();
}
template<typename T>
static void reg(std::string& s) {
map.insert(std::make_pair(s, &create<T>));
}
};
Thanks in advance.
And unrelated to the error, but is there a way to let Bullet include BulletFactory without creating tons of errors (because of circular inclusion)? This way I would be able to remove #include "BulletFactory.h" from the top of all of the bullet subclasses.
I don't think you can call functions outside of functions (as long as you don't use the result to initialize a global).
Here's how you get what you want. (Not using your code, exactly, skips including headers, etc. Just for the idea.):
// bullet_registry.hpp
class bullet;
struct bullet_registry
{
typedef bullet* (*bullet_factory)(void);
std::map<std::string, bullet_factory> mFactories;
};
bullet_registry& get_global_registry(void);
template <typename T>
struct register_bullet
{
register_bullet(const std::string& pName)
{
get_global_registry().mFactories.insert(std::make_pair(pName, create));
}
static bullet* create(void)
{
return new T();
}
};
#define REGISTER_BULLET(x) \
namespace \
{ \
register_bullet _bullet_register_##x(#x); \
}
// bullet_registry.cpp
bullet_registry& get_global_registry(void)
{
// as long as this function is used to get
// a global instance of the registry, it's
// safe to use during static initialization
static bullet_registry result;
return result; // simple global variable with lazy initialization
}
// bullet.hpp
struct my_bullet : bullet { };
// bullet.cpp
REGISTER_BULLET(my_bullet)
This works by making a global variable, which will be initialized at some point during static initialization. When that happens, in its constructor it accesses the global registry and registers it with the name, and the function used to create bullets.
Since static initialization order is unspecified, we put the global manager in a function, so when that function is called the first time the manager is created on-demand and used. This prevents us from using an uninitialized manager, which could be the case if it were a simple global object.
Free free to ask for clarifications.
reg() is a function. You can't call a function without a scope.