Passing Vector to function while using Graph - c++

I wrote my code like this inside a class to calculate max distance from source to node. Now I need to take it out of the class and have a similar function to calculate my distances but by using Djikstra. So, I would need to pass this city vector and source being one of my vertex ( this will loop over vertices ) and return a distance from this function back to class for my next computation. I am running out of time so help me.
int distanceToNearCity(int cityIdOfStore, const std::vector<City> & AllCities) const
{
// is there a store in this city ?
if (storeExists || cityId == cityIdOfProposedNewStore)
{
return 0; // 0 distance
}
int distance = TOOFAR; // initialise with more than max allowed
for (int i=0; i<connectingCities.size(); ++i)
{
int id = connectingCities[i];
if (AllCities[id-1].hasStore() || AllCities[id-1].getId() == cityIdOfProposedNewStore)
{
// we have a store (or proposed one) here, but is it's distance more than other stores ?
if (distances[i] < distance)
{
distance = distances[i];
}
}
}
return distance;
}
How can I pass these class objects to function which is public.Thanks!!

Well, accessing internal member variables from main is problably a bad design, breaks encapsulation, is a possible source of problems, thus not a good idea.
Solution 1
Let's say your class is called MyOriginal. Make distanceToNearCity virtual. Create a derived class MyDerived and rewrite distanceToNearCity so that implements Djikstra. In the derived class you can access the original member variables from MyOriginal, as long as they are public or protected. The user (main) does not need to know the implementation details.
Solution 2
Rewrite the original distanceToNearCity method so, that it has no side effects as it ware a static method. This means that it does not need access to any of the member variables. Pass all arguments to the method via parameters. I mentioned 'as it was a static method', since the method will not be the member of the original MyOriginal class. Make MyOriginal a template class, implement distanceToNearCity in an external class and pass this class as a template argument to MyOriginal. As a non member, you can implement any number of distance algorithms and pass them to the original class. This solution has the advantage, that the call to the 'virtual' method is known at the compile time, so it produces faster code.
template<class T> // T will contain distance computation
class MyOriginal
{
public:
void process()
{
.. // your staff
int distance = T::distanceToNearCity(necessary arguments); // call the external implementation
.. // rest of your staff
}
};
class OriginalDistance
{
public:
static int distanceToNearCity(necessary arguments); // your original implementation
};
class DjikstraDistance
{
public:
static int distanceToNearCity(necessary arguments); // another distance computation
};
int main(int argc, char *argv[])
{
MyOriginal<DjikstraDistance> myInstance;
myInstance.process(); // call processing, use DjikstraDistance::distanceToNearCity() inside
}
Solution 3
If you from some reason dislike both previous implementations, you can use a 'c' style solution. Create a type which represents a signature of the distanceToNearCity method.
Write 'distanceToNearCityOriginal' and 'distanceToNearCityDjikstra' functions. Pass a pointer to desired function as a paramter the MyOriginal::process method. C++ developers will dislike you.
typedef int (DistanceAlgo*)(necessary arguments); // pointer to a function which returns int
int distanceToNearCityOriginal(necessary arguments); // first implementation of distance
int distanceToNearCityDjikstra(necessary arguments); // second implementation of distance
class MyOriginal
{
public:
void process(DistanceAlgo algo)
{
.. // your staff
int distance = (*algo)(necessary arguments); // call the external implementation
.. // rest of your staff
}
};
int main(int argc, char *argv[])
{
DistanceAlgo algo = &distanceToNearCityDjikstra; // choose djikstra
MyOriginal myInstance;
myInstance.process(algo); // call processing, use distanceToNearCityDjikstra inside
}

Related

I want a function that has child functions to access the same named function, without it depending the class of it's child class

So basically, I want my first class to be a basic one, just like in the example down below, to be inherited, and the child classes which come out of it, to have a same named function, that will return the fictional price of something, but I don't know how to access the functions while writing a void function out of classes, which recieves an array of pointers of the basic class and then the number of array elements, then calls for the same named function in both child classes.
Take a look yourself.
While you're at it, feel free to tell me any errors I've made along the way, regards!
#include <iostream>
#include <cstring>
#include <ctype.h>
using namespace std;
class basic{
protected:
char name[20];
public:
basic(char * n)
{
strcpy(name,n);
}
};
class advanced1:public basic{
protected:
float price;
public:
advanced1(char * n, float p):basic(n)
{
price=p;
}
float priced()
{
if(price<10)
return price*1.5;
else
return price*1.2;
}
};
class advanced2:public basic{
protected:
float price;
public:
advanced2(char * n, float p):basic(n)
{
price=p;
}
float priced()
{
if(price<15)
return price*2.3;
else
return price*1.8;
}
};
void printstuff(basic *basics[], int basicsN)
{
for(int i=0;i<basicsN;i++)
{
cout<<basics[i]->priced();
}
}
What you are describing is a "virtual" function. You can follow this tutorial.
Looking at your code, it seems like you don't actually want the base class to implement the function. For that you'd have to use a pure virtual function - see this link. But keep in mind that using a pure virtual function means that you cannot directly instantiate the base class.
And about errors, just on first glance, the way you use strcpy could write beyond the end of the name array. I recommend using strncpy (see this) instead and specifying the number of characters. If you want to copy exactly 20 characters always, you could specify 20, or if 20 is just the limit, you could use strlen to get the length of the incoming string and then copy std::min(20, length) characters.

Use Members of One Class in Another Class (OOP)

I have two classes Instructor and Game.
Instructor.h
class Instructor
{
int instrID;
public:
Instructor();
void showGameStatus();
int createGame();
vector<int> createGames(int numberOfGames);
};
Game.h:
class Game {
private:
int gID;
int instrID;
int pFactID;
public:
Game() { // default constructor
gID = 0;
instrID = 0;
pFactID = 0;
};
These are in Instructor.cpp
void Instructor::showGameStatus()
{
}
int Instructor::createGame()
{
Game g;
}
CreateGame() initializes a game. I want that upon calling showGameStatus() I can print out all properties (eg gId, InstrId) of the Game g that initialized earlier etc.
Is it possible to access the properties of Game g that in another method?
This should do it. Class Instructor should inherit class Game:
class Instructor::public Game{
your code here
}
The short answer is: No.
The longer answer is this: If I understand correctly, what you want to accomplish, the problem is that the object g of type Game is held by a local variable inside the scope of your Instructor::createGame member function. Once that function is "done", i.e. the local scope ends, the object, which has automatic storage will be destroyed. It's gone. I don't know what the int means that you return, but no matter what it does, it doesn't hold an object of type Game.
Now, you probably want your createGame to return some type of handle to an actual Game object. Depending on your specific setting, it is your job to choose how to pass such an object around. For example, one way might be this:
Game Instructor::createGame() const { // 1
Game g;
// do stuff with g, perhaps?
return g;
}
Another might be:
std::unique_ptr<Game> Instructor::createGame() const { // 2
auto gptr = std::make_unique<Game>();
// do stuff with gptr, perhaps?
return gptr;
}
Or yet another:
std::size_t Instructor::createGame() { // 3
// Instructor has a member std::vector<Game> games
games.emplace_back();
// do stuff with games.back()
return games.size()-1;
}
There are countless other ways to pass the object around.
No matter what you choose you have to pass something to identify which Game object you are talking about back into your showGameStatus function, if you plan to have more than one Game object flying around (I assume you do).
auto some_handle = instructor.createGame();
// ... later ...
instructor.showGameStatus(some_handle);
This all holds true, if you want more than one object. Otherwise you might want to just add the object as a member of your Instructor type:
class Instructor {
private:
Game game;
public:
Instructor() : game() {}
// no createGame function, it is superfluous
void showGameStatus() const {
game.some_output_function();
}
};
Just inherit the Instructor Class into the Game Class and do your work...

Inheriting from std:: vector

I am currently creating a class that has to be derived from std:: vector. I realize its probably bad to do this but I'm required to. Now my question is how do you access the created vector in the member functions to basically make the class access itself like a regular vector of integers? For example I am looking for the equivalent of myVector.at(0) to return the first term in the vector. Also, the size of the vector should always be 6. Here is the code I have so far:
class aHistogram : public vector<int>
{
public:
aHistogram(); //default constructor for histogram class
void update(int face); //Function to update histogram
void display(int maxLengthOfLine); //Displays histogram to the scale of maxLengthOfLine using x's
void clear();//Function to clear histogram bin counts
int count(int face) const; // Function to return number of times a face has appeared
private:
int numx, m, j; //Variables used in functions
};
#endif
The function that requires the class to access itself is below, I know there is no vector called "myVector" but what I'm lost about is the equivalent syntax to be able to perform the operation.
void aHistogram::clear()
{
//Clears bin counts to 0
myVector.at(0) = 0;
myVector.at(1) = 0;
myVector.at(2) = 0;
myVector.at(3) = 0;
myVector.at(4) = 0;
myVector.at(5) = 0;
}
If the function in question isn't overridden in the derived class, you
can just call it:
void HistoGram::clear()
{
at( 0 ) = 0;
// ...
}
This is also true for operators, but you'll have to use (*this) as the
left hand operator:
void HistoGram::clear()
{
(*this)[0] = 0;
// ...
}
If the function or operator is overridden, you'll either have to
qualify the function name,
void HistoGram::clear()
{
std::vector<int>::at( 0 ) = 0;
// ...
}
or cast the this pointer to the base class type:
void HistoGram::clear()
{
(*static_cast<std::vector<int>*>( this ))[0] = 0;
// ...
}
But are you sure that you want public inheritance here? You state that
the size of the vector should always be 6. There's no way you can
guarantee that using public inheritance; at the least, you need private
inheritance, and then using declarations for the operations that you
want to support. (I've a couple of cases where I've needed restricted
std::vector like this, which I've implemented using private
inheritance. And sometimes forwarding functions, when for example
I've wanted to expose only the const version of the function.)
Also: there are very, very few cases where std::vector<>::at is
appropriate. Are you sure you don't want [], with the bounds checking
you get in most modern implementations.
Instead of deriving from std::vector, in this case contain one (as a data member).
The problem with deriving is that it's then possible to treat a Histogram instance as just a std::vector, doing things that invalidate assumptions about the values of added data members.
In more technical jargon, with class derivation you have no guaranteed class invariant above the one provided by std::vector.
As a general rule of thumb, think of data member before class inheritance.
Sometimes inheritance is the thing, even inheritance from standard library container classes (e.g., std::stack is designed for inheritance), but not in this case.
About this: the size of the vector should always be 6.
You probably want to forbid some functionality to the user of the class. For example
vector::push_back
vector::pop_back
vector::insert
are functionalities that can change the size of the vector.
You can achive this by making such functions private members in the child class:
class aHistogram : public vector<int>
{
public:
aHistogram(){};
private:
vector<int>::push_back;
vector<int>::pop_back;
vector<int>::insert;
int numx, m, j;
};

Changing int value from a class function

I have a shape class that I initialize from my main program and give the parameters in the constructor.
Shape *cusomShape = new CustomShape(float radius, float origin)
The shape class has some functions such as rollover and more.
When the rollover function inside the shape class is fired, I want to change a certain int value in the main program. This might similar to firing of an event that changes the value when the rollover function is fired, but I am not sure how to do that in C++. If at all, events is the ideal approach here, it would great to see a short example coming.
If using the event is not the correct, what would the ideal way to go about this?
I think what you need is to pass a value by pointer or reference to the function in Shape and then modify it. If the function is called not from main but from somewhere else passing the pointer is the better option you have. First pass the pointer to the class and store it using another method and then each time rollover is called make use of it.
EDIT: example:
class CustomShape {
void storePointer(int* _value) {
value = _value;
}
void rollover() {
.. do stuff
*value++; // for instance
... do stuff
}
int * value;
}
int main() {
int a;
CustomShape cs;
cs.storePointer(&a);
....
cs.rollover();
....
return 0;
}
Pass a reference to the variable in the constructor and save that reference. Change the value when needed.
I would suggest passing a reference to the variable to the member function that needs to change its value. Storing a reference in a class couples the Shape class to the reference. This means that each time you want to use the Shape, without updating the integer, you cannot, since the Shape constructor will expect a reference/pointer to the int as an argument (the Shape class will store the pointer/reference as an attribute). Passing a reference/pointer to the member function promotes Low Coupling.
#include <iostream>
class Shape
{
double shapeValue_;
public:
Shape (double value)
:
shapeValue_(value)
{}
void fireFunction(int& updateMe)
{
updateMe = 123;
}
};
using namespace std;
int main()
{
int update;
cout << update << endl;
Shape s(4.5);
s.fireFunction(update);
cout << update << endl;
return 0;
};
And in this case, you have an option for a main program that doesn't involve shape object calling on fireFunction:
int main()
{
Shape s(4.5);
// Main program that doesn't use fireFunction.
return 0;
};
In this case, if you have member functions changing input arguments, you should take on a style for defining such functions: e.g. make sure that the variable that gets changed by the member function is always the first input argument in its declaration.
If you want complex objects to communicate updates between each other, you can make use of the Observer Pattern.

Is it possible to pass a variable out of a class without creating a new object in C++

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.