Here is my concrete example of what I'm trying to do. I need to have a type of object created by the end of this function so I can store it in something else(not created yet), that is either a string, Id, or expression parameter. The problem I am facing is that I don't know what type of object to create if I haven't done logic yet, and If I create the object inside the if statement while I am doing logic, it will exist no more there. I want to store the objects into a vector of type parameter in another class not listed here. at the end of the code
bool parameter(Predicate& pred)//look for the following: STRING | ID | expression
{
//store a parameter in this predicate
Parameter // <- I don't know which type of object to create yet!!!!
//create parameter
get_grammar_type(token, sfile);
token_type = token.Get_type();
if(token_type == STRING)
{
//would create object of type string here
//can't create object here. It won't exist after.
}
else if(token_type == ID)
{
//would create object of ID string here
//can't create object here. It won't exist after.
}
if(expression(pred))
{
//would create object of Expression here.can't create object here. It won't exist after.
}
//store object in object pred here. Pred has a private member of a vector of type parameters within it.
return true;
}
#ifndef PARAMETER_H
#define PARAMETER_H
#include <string>
#include <vector>
#include "Predicate.h"
using namespace std;
class Parameter
{
public:
private:
}
class String : public Parameter
{
public:
insert_string(string in_string);
private:
string my_string;
}
class ID : public Parameter
{
public:
insert_id(string in_ID);
private:
string my_ID;
};
class Expression : public Parameter
{
private:
Parameter left_parameter;
Parameter right_parameter;
string op;
public:
};
#endif
//also I want to know how I will be able to create left and right parameters in the expression class if i don't know what type they are yet
You can use pointers in this case. Create a Parameter* variable further up, and dynamically allocate the data structure inside one of your if-statements and assign to that pointer. For example:
Parameter *parameter = NULL;
if(token_type == STRING)
{
parameter = (Parameter*) new String();
}
Do something fancier with smart pointers if you don't want to worry about deallocation.
Related
I'm trying to call a method to add to an object to a vector within another object. I'm getting the error;
'': Illegal use of this type as an expression
Within my program I declare an object to store my node in the main;
accountStream *accountStore = new accountStream;
Then call the function;
new_account(&accountStore);
The new_account function is as;
void new_account(accountStream &accountStorage)
{
newAccount *account = new newAccount;
(&accountStorage)->pushToStore(account);
}
The account stream class has a vector that receives it, but there is where my error is;
class accountStream
{
public:
accountStream();
~accountStream();
template <class account>
void pushToStore(account);
private:
std::vector <newAccount*> accountStore;
};
template<class account>
inline void accountStream::pushToStore(account)
{
accountStore.push_back(account);
}
The error is on the second last line;
accountStore.push_back(account);
I've got a feeling it's something to do with the way I'm passing the object into the method, but after messing around for a while I haven't been able to pinpoint where exactly I've gone wrong.
2 problems:
new_account(&accountStore); is wrong, use new_account(*accountStore); to match the argument type.
accountStore.push_back(account); is wrong. account is type not object. Add some argument to the function.
Several issues:
You must specify the variable name here (and not only the type):
template<class account>
inline void accountStream::pushToStore(account c)
{
accountStore.push_back(c);
}
You must receive a pointer (not a reference to a pointer) here
void new_account(accountStream *accountStorage)
{
newAccount *account = new newAccount;
accountStorage->pushToStore(account);
}
You must call the function with a pointer as a parameter:
new_account(accountStore);
Alternatively, you can declare the variable (not a pointer to):
accountStream accountStore;
call the function:
new_account(accountStore);
and receive a reference:
void new_account(accountStream &accountStorage)
{
newAccount *account = new newAccount;
accountStorage.pushToStore(account);
}
As answered here already, you need to use *accountStore and not &accountStore because the function takes a reference and not a pointer to a pointer (which is what you get from using & operator on a pointer).
the second problem is here:
template<class account>
inline void accountStream::pushToStore(account)
{
accountStore.push_back(account);
}
you are declaring the function templated on the 'account' therefore account is a type, and what you are trying to do in the next line is push_back a type and not an object.
the correct code would be:
template<class account>
inline void accountStream::pushToStore(account acct)
{
accountStore.push_back(acct);
}
because account is the type while acct is an instance of the type account.
I want to learn how to use class object within class, especially how to pass an arguments between the objects. I'm trying to create an example object Calc which should provide two methods Calc.sum and Calc.sub. It should use another object Plus as a math engine. The Plus.add function compile and works well. But I don't know how to initiate multiple instance of plus in the calc. The code:
class Plus{ // This class works well
public:
Plus(int); // Structure
int add(int); // Public method (function)
int myVar; // Public property. Just to hold a value.
private:
int _init; // Class-level private variable
};
Plus::Plus(int init){ // Constructor
_init = init;
}
int Plus::add(int p){ // Method add
return _init + p;
}
/***************************************************************************/
class Calc{
public:
Calc(int); // Structure
int sum(int); // Method sum
int sub(int); // Method sub
int myVar; // Public property
private:
Plus positive(int); // Class-level private object definition ?
Plus negative(int); // This is probably wrong ??
};
Calc::Calc(int init){ // Constructor (also wrong...)
Plus positive(init); // Create object "positive" and pass the initial value
Plus negative(-init); // Create object "negative" and pass the initial value
}
int Calc::sum(int n){
return positive.add(n);
}
int Calc::sub(int n){
return negative.add(n);
}
/***************************************************************************/
Plus two(2); // Create class object two
Calc five(5); // Create class object five
void setup(){
Serial.begin(115200);
Serial.print("two.add(3) = ");
Serial.println(two.add(3)); // Calling instance of class Plus
two.myVar = 100;
Serial.println(two.myVar);
Serial.print("five.sum(3) = ");
Serial.println(five.sum(3)); // Calling instance of class Calc
Serial.print("five.sub(3) = ");
Serial.println(five.sub(3)); // Calling instance of class Calc
}
void loop(){}
My example is inspired by this article: http://arduinoetcetera.blogspot.cz/2011/01/classes-within-classes-initialiser.html but the code there is for one instance only
1) How to declare multiple instances of Plus within Calc
2) Is the terminology (comments) right?
Your problem lies here
Calc::Calc(int init){ // Constructor (also wrong...)
Plus positive(init); // Create object "positive" and pass the initial value
Plus negative(-init); // Create object "negative" and pass the initial value
}
By doing this, you're creating local variables with the same name as your members: it has no effect.
Should be
Calc::Calc(int init): positive(init),negative(-init)
{
}
That way you initialize your members even if your members don't have a default constructor.
Oh and that is also wrong in definition of Calc
Plus positive(int); // Class-level private object definition ?
Plus negative(int); // This is probably wrong ??
replace by
Plus positive; // Class-level private object definition
Plus negative;
I'm having a little bit of a hard time explaning the problem, so here's a simple rundown of my code:
Imagine I have a class called 'character'
#include "myEnums"
#include "weapon"
character {
protected:
string characterName;
weapon* myWeapon;
public:
string getCharacterName();
void setCharacterName( string );
string getMyWeapon();
void setMyWeapon();
}
Then within 'setMyWeapon' I use this simplified code.
void character::setMyWeapon() {
this->myWeapon = new weapon("longsword");
//this->myWeapon = new weapon(myEnums::LONGSWORD); //Ideally this
}
string getMyWeapon() {
return this->myWeapon.tostring();
}
But when I type the '.' for 'myWeapon' there's no members, anyone know whatup? Assume 'tostring' is defined in 'weapon.h'...
Since myWeapon is a pointer, you need to dereference it to access the pointee's members:
myWeapon->tostring()
// ^^^^
I'm writing a C++ program using Code::Blocks. I want to make a doubly linked list.
My plan is to make an node class called geoPoint with pointers north and south to other nodes. I've written a test function to create and link two nodes, then traverse them with a third node. Here's what I have so far:
#include <iostream>
#include <string>
using namespace std;
class geoPoint
{
public:
geoPoint *north, *south;
private:
string description;
public:
void showDesc()
{
cout << description << endl;
};
void setDesc(string sourceText)
{
description=sourceText;
};
void setNorth(geoPoint sourcePoint)
{
north= &sourcePoint;
}
void setSouth(geoPoint sourcePoint)
{
south= &sourcePoint;
}
};
int main()
{
geoPoint testPoint,testPoint2,currentPoint;
string sourceText("testPoint");
string sourceText2("testPoint2");
testPoint.setDesc(sourceText);
testPoint2.setDesc(sourceText2);
testPoint.setNorth(testPoint2);
testPoint2.setSouth(testPoint);
currentPoint=testPoint;
currentPoint.showDesc();
currentPoint= ¤tPoint.north;
currentPoint.showDesc();
cin.get();
return 0;
};
main() crashes when it gets to the line currentPoint= ¤tPoint.north;. The error message is:
error: no match for 'operator=' in 'currentPoint = & currentPoint.geoPoint::north'
I thought that a=&b is the right way to assign the dereferenced contents of pointer b to variable a. What am I doing wrong?
currentPoint is of type geoPoint. ¤tPoint.north is of type geoPoint**. & is the address-of operator: you're taking the address of a geoPoint*, which stores the address of a geoPoint.
If you want currentPoint to hold a copy of the geoPoint to which currentPoint.north refers, use the dereference operator *, as in *currentPoint.north. However, if you merely want to refer to the object without copying it, change currentPoint to a geoPoint* and write this instead:
currentPoint = currentPoint->north;
In the functions setNorth and setSouth you are taking the address of a temporary object (the parameter). This pointer will be invalid as soon as the function returns.
Did you, by any chance, intented to write
currentPoint= *currentPoint.north;
?
I have a variable, which is a member of one of my classes, that another is in need of, but I'm not sure how to effectively pass the value between them without using a global variable, which is something I'd like to avoid if at all possible. I know I could create an object, but that would invoke the constructor of the originating class which would execute a number of functions and write the needless results to memory, which would be wasteful of system resources.
Is there an easy way to pass this value between the two functions?
Update: The class that is in need of the variable, called no_of_existing_devices. The purpose of class Initialise is to open up a file and count the number of lines of test it contains, and place that number in the variable int no_of_existing_devices, which is then used by the Device::Device() to create an object for each
class Device
{
public:
void view_attribute_list();
void set_attribute();
Device();
};
Device::Device()
{
for (int count = 0; count < no_of_existing_devices; count ++)
{
// Create an object for each iteration, up to a maximum of no_of_existing_devices
}
}
The class of which this variable is a member
class Initialise
{
public:
int no_of_existing_devices;
bool initialisation;
string existing_device_list[100];
void initialise_existing_devices();
Initialise();
};
Initialise::Initialise()
{
no_of_existing_devices = 0;
}
void Initialise::initialise_existing_devices()
{
string line;
ifstream DeviceList;
DeviceList.open("devices/device_list");
while (true)
{
getline(DeviceList, line, '\n');
if (DeviceList.eof())
{
break;
}
++ no_of_existing_devices;
}
DeviceList.close();
DeviceList.open("devices/device_list");
for (int i = 0; i < no_of_existing_devices; i ++)
{
getline(DeviceList, line, '\n');
existing_device_list[i] = line;
}
Device existing_devices[no_of_existing_devices];
!initialisation; // Existing devices are now initialised
}
Okay, from what I understand:
You don't want to have a global
You don't want to have a static
You don't want to introduce a dependency between Device and Initialise
There is one other option, assuming something owns Device and Initialise, move the no_of_existing_devices up to there, then construct both Device and Initialise with a reference to this variable...
In a similar circumstance I was just passing the pointer to the member --- I had to invoke a member function then, so it was a pointer to the member function, http://www.parashift.com/c++-faq-lite/pointers-to-members.html
It's a bit messy, but it works :-).
If the variable in the originating class can hold a value without an instance of the class I would assume that the variable is static. If not create a public static member of the class. And use it in the target class.
Something like:
// .h file
class A
{
public:
static int a;
}
// .cpp file
int A::a = 123;
// .cpp file of class B
void B::foo()
{
cout << A::a;
}
If it is a class attribute (internal variable), then you can obtain a reference through a get method. Otherwise, you can use the friend keyword on the class you want to access the attribtue from the other For example, if you declare friend class B; on class A, the attributes of the class B will be accessible on the class A.
I suggest you use the first method in order to maintain your code OO pure ;)
Edit: of course, if you access through a reference there are no resources wasted :)
Edit 2: use a static method on Initialise class that returns the no_of_existing_devices and call Initialise::NoOfExistingDevices() on the Device class. If you want to resources use a pointer like this:
public static int* Initialise::NoOfExistingDevices() {
return &no_of_existing_devices;
}
By the way, I advise you to turn the variable private.