Below...
Below...
Last edited by tallguy; 04-03-2007 at 08:31 PM.
Now I'm curious. What was the error and what caused it?
Ok I've got a new error now.
I am trying to store actors as vertices for the Kevin Bacon Game. But for each actor I stored an integer which is an index in the vector that contains the actors. However, when I try to print each actor in the function above, I'm sure I am not accessing the actor in the vector correctly the way I have done it because the program terminates.Code:void Graph::printPath( const Vertex & dest ) const { if( dest.prev != NULL ) { printPath( *dest.prev ); cout << " was with "; } ActorDB::tag t = dest.a; cout << (*data)[t].name(); ----------Where I believe the problem is }
Some of the other files...
Graph.h...
ActorDB.hCode:#include <iostream> #include <string> #include <sstream> #include <fstream> #include <list> #include <map> #include "GraphStuff.h" #include "ActorDB.h" struct Vertex; class Graph { public: Graph( ) { } Graph( vector<Actor> * d ) : data(d) { } ~Graph( ); void addEdge( const ActorDB::tag & sourceName, const ActorDB::tag & destName, double cost ); void printPath( const ActorDB::tag & destName ) const; void unweighted( const ActorDB::tag & startName ); //void dijkstra( const std::string & startName ); void addVertex (const ActorDB::tag & startName); private: Vertex * getVertex( const ActorDB::tag & vertexName ); void printPath( const Vertex & dest ) const; void clearAll( ); typedef map<int ,Vertex *,less<ActorDB::tag> > vmap; // Copy semantics are disabled; these make no sense. Graph( const Graph & rhs ) { } const Graph & operator= ( const Graph & rhs ) { return *this; } vector<Actor> * data; vmap vertexMap; };
#endif /*ACTORDB_H_*/Code:#ifndef ACTORDB_H_ #define ACTORDB_H_ #include "Actor.h" #include <vector> /** * This object holds all the actor objects in our program in exactly one place. * When you add an actor to the database, you get a "tag" back. Keep that tag, * so that when you want the actor again, you can get it. Tags are small, and * lookup is fast (constant time). */ class ActorDB { public: /// The abstract type used by clients to reference the stored Actor objects. typedef unsigned int tag; /** * Create an empty database. */ ActorDB(); /** * Destroy the database and all of the actors in it. All tags are now, of course, * invalid. */ ~ActorDB(); /** * Add an actor to the database, and get a tag back that refers to it. Runs in * constant time (amortized). Note that this function does not check for duplicates * before inserting, since in common applications this isn't necessary. * * @param a The actor to be stored. A copy will be placed in the database. * @return a tag object that can be used to get the stored Actor. */ tag add_actor(const Actor& a); /** * Retrieve a reference to the stored Actor based on a tag. Runs in constant time. * * @param t a tag referring to some entry in our database * @return a constant reference to the stored Actor. */ const Actor& get_actor(tag t) const; unsigned int getTag(const Actor & a) const; private: std::vector<Actor> data; };
Last edited by tallguy; 04-03-2007 at 09:06 PM.
Ok I believe my problem is that when I create my Graph object I am not passing it the correct reference to the vector.
That is how I'm currently calling it which calls the default destructor.Code:static Graph actorGraph;
But I need to pass it a reference of the vector stored in my ActorDB class. So I created a function in my ActorDB.cpp class to return the reference to the vector:
But now I don't know how to access this funtion from my Movie class, which is where I create my graph. I tried calling it with:Code:vector<Actor> * ActorDB::pointer() { return &data; }
But that's just an error. Anyone know how I can call this function from my Movie class?Code:static Graph actorGraph(adb->pointer());
The vector in your Actor class is not static, meaning one will only be created when you create an ActorDB instance. This is fine, if you have an ActorDB instance somewhere in your program. However, the Movie class's actorGraph is static, so it is created at the start of your program, most likely before the ActorDB instance. So you cannot pass the pointer to it. If you could, you would do it in the cpp file where you define the actorGraph:I think a better idea would be to use the default constructor for the graph and then have a setActorList (or whatever) function to actually set the pointer and do all the construction work later.Code:Graph Movie::actorGraph(adb->pointer());
Where would the setActorList function to set the pointer go?
In the Graph class. It would do the same thing the Graph( vector<Actor> * d ) constructor does, which is set the data pointer to d.
If you meant where would you call it, I would call it as soon as adb is created. You can do that in the adb constructor, or in regular code just after that variable is created. I'm not sure which is better, it may not matter.
If the actorGraph is private to Movie, then you may have to make another function in Movie similar to setActorList which just calls the actorGraph's setActorList. This might be necessary since the private actorGraph wouldn't be accessible outside the Movie class.
Ok so in graph.h I put
and in graph.cpp I putCode:std::vector<Actor> * setActorList();
I don't think this is right?Code:std::vector<Actor> * Graph::setActorList() { return &data; }
>> I don't think this is right?
I don't think its right either. That is how you would write a getActorList() function. You want a setActorList() function. The second Graph constructor is essentially exactly what you want, except it has no return type because it is a constructor. Just change the name and make it void, then save the pointer inside the function.
Ok so in graph.h i have
and in graph.cpp i haveCode:class Graph { public: Graph( ) { } Graph( std::vector<Actor> * d ) : data(d) { } ~Graph( ); void addEdge( const ActorDB::tag & sourceName, const ActorDB::tag & destName, double cost ); void printPath( const ActorDB::tag & destName ) const; void unweighted( const ActorDB::tag & startName ); //void dijkstra( const std::string & startName ); void addVertex (const ActorDB::tag & startName); void setActorList(vector<Actor> * a); ------------>new function
But I'm not sure where or how to call this function with the vector from the ActorDB class.Code:void Graph::setActorList(vector<Actor> * a) { data = a; }
Well my program is pretty big but if any of you want to look at the files to see if I am going wrong anyplace else here they are:
Actor.cpp http://rafb.net/p/ubeLtL52.html
Actor.h http://rafb.net/p/1KBtdH80.html
ActorDB.cpp http://rafb.net/p/bKnIUq12.html
ActorDB.h http://rafb.net/p/fAwiBP80.html
App.h http://rafb.net/p/FaBJil25.html
App.cpp http://rafb.net/p/ChP4QR39.html
Graph.cpp http://rafb.net/p/Emg74h74.html
Graph.h http://rafb.net/p/e26FkO22.html
Graphstuff.h http://rafb.net/p/aRTVQF44.html
main.cpp http://rafb.net/p/SHpaYr31.html
movie.h http://rafb.net/p/P3pQsw41.html
movie.cpp http://rafb.net/p/efOgEk83.html
MovieDB.h http://rafb.net/p/gBZ0mv86.html
MovieDB.cpp http://rafb.net/p/2yjD8977.html
In the constructor perhaps? Then you could have a constructorBut I'm not sure where or how to call this function with the vector from the ActorDB class.
BTW colours stand out better than lots of hyphens IMHO.Code:Graph::Graph(vector<Actor> * a) {}
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.