I am trying to write my code without using global variable as most people told me it was a bad habit, so I am changing how my program works.
I am having problem with passing multiple instance of a class to another class. I need to be able to modify the multiple instance of a class in the other class.
Here is what I am trying to do but failing miserably at it :
int main() {
Players *player[6];
//preparing 6 instances of Players() so I can loop through them in another class
for (int i = 0;i<6;i++){
player[i] = new Players();
}
player[0]->name = "fluffy";
Players.h
#ifndef PLAYERS_H_
#define PLAYERS_H_
#include <string>
#include <vector>
class Players {
public:
Players();
virtual ~Players();
std::string name;
bool hand;
int cif;
int id;
std::vector<int> autho;
std::vector<int> collec;
std::vector < std::vector <int> > puppet;
};
#endif /* PLAYERS_H_ */
Players.cpp
#include "Players.h"
Players::Players() {
// TODO Auto-generated constructor stub
name = "";
hand = false;
cif = -1;
id = -1;
}
Players::~Players() {
// TODO Auto-generated destructor stub
}
Now I want to call another class (doesn't matter which) and I want to pass the multi instanced class Players to it so it can read and do modification to the data within these instanced classes.
For example a class with a function that could read player[0]->name and modify it to "sandpaper"
How would you approach this without getting errors from the compiler?
I am open to suggestion for a completely different way to approach this ( I have tried to use struct variables and pass it but I got other problems as well)
thank you,
Kaven
First of all, I'd approach this by using std::vector<Players> (not pointers!). Secondly, I'd just pass this vector by reference to other functions.
I suggest to approach like this:
int main()
{
unique_ptr<vector<Player>> playersVector (new vector<Player>);
for (int i = 0;i<6;i++)
{
playersVector->push_back(Players());
}
playersVector->at(0).name = "fluffy";
}
And then if you want to pass that vector with ownership to some method or class use:
move(playersVector)
If you want have ownership in main class pass by normal pointer:
playersVector.get()
I also suggest using Get/Set methods instead of accessing class fields directly
Related
I have a base class named shapes with derived class of a 3D shape, i.e. Ball or Tetraeder.
My program should read the type of the shape and it's parameters from a text file and write the volume and area to an output text.
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "Shape.h"
#include "Ball.h"
#include <vector>
using namespace std;
int
main( int argc, char** argv )
{
string input = string(argv[1]);
string output = string(argv[2]);
ifstream file(input);
string line;
string shapename;
int nx = atoi(argv[3]);
int ny = atoi(argv[4]);
int nz = atoi(argv[5]);
while (std::getline(file, line))
{
std::stringstream lineStream(line);
lineStream >> shapename;
int value;
std::vector<int> lineData;
while (lineStream >> value)
{
lineData.push_back(value);
}
Shape * objShape = new shapename(lineData);
objShape -> calc_volume;
objShape -> calc_projection(nx,ny,nz);
std::ofstream f(output);
f << objShape -> get_volume() << " " << objShape -> get_projection << endl;
}
}
My Question is now how can i create an object from a string in a textfile, especially without knowing all derived classes.
It should be possible to add more shapes to the program without changing the code, only by adding new files.
The question is:
My Question is now how can i create an object from a string in a
textfile, especially without knowing all derived classes.
The answer is: you have to know all the derived classes.
C++ does not have reflection. As such all class names are bound at compile time, and this kind of a factory has no choice but to do some variation of:
if (name == "box")
return new Box();
else if (name == "circle")
return new Circle();
// ... etc ... etc ...
There are various different approaches and design patterns that make it possible to automate some of this drudge work, and make this flexible enough to avoid having to explicitly maintain a hardcoded list of all subclasses.
I'll just outline a brief, very brief approach. A very simple one that I've used before, and achieves, pretty much, the same result: a factory that can instantiate a given subclass by name, in a manner where you don't have to manually edit the factory, and add a few more lines of code. The entire process of creating a factory for a new subclass can be neatly wrapped into the process of creating a new subclass, making this a fairly bulletproof, compartmentalized solution.
Consider a simple mechanism for registering a factory for these subclasses:
typedef Shape (*shape_factory_t)();
Shape is your superclass of shapes.
The factory would work something like this:
std::map<std::string, shape_factory_t> all_factories;
void register_factory(const std::string &name, shape_factory_t factory)
{
all_factories[name]=factory;
}
So now you have a map of all your factories. Instead of an endless if statement you have a single map, which you can look up by class name, and call the appropriate factory, something like:
auto iter=all_factories.find(name);
if (iter == all_factories.end())
throw; // Some exception, unknown subclass
return (*iter->second)();
All right, that part's taken care of. The issue now becomes: how to register a factory for each subclass.
Let's say you have an implementation of Circle:
class Circle : public Shape {
class initializer;
// ... other things that make up the Circle
};
Then, in circle.cpp, which implements this subclass:
static Shape *create_circle()
{
return new Circle(); // Add constructor parameters, as appropriate
}
class Circle::initializer {
public:
initializer() {
register_factory("circle", create_circle);
}
};
static initializer initialize_me;
In this manner, the Circle class registers itself with the factory that creates an instance of a given Shape, by class name. You can proceed and implement all other subclasses, individually, without touching the main factory code. You can declare your Box subclass in the same manner, and have it register itself with the factory, which will then automatically know to create a Box class (presumably by invoking the create_box() function), given the name "box".
There is one other detail that needs to be taken care of: initialization order. As you know, the relative initialization order of globally-scoped objects in different translation units is implementation defined, and is otherwise unspecified by C++.
The global std::map of all factory functions must be constructed before all the subclasses try to register themselves, and put themselves into the map, when the application starts.
This is a fairly typical static initialization order fiasco question, for which there are several known solutions. The one explained in this answer should work fine, here.
C++ isn't so flexible. Adding new shapes would mean adding new classes (since you have already made a Shapes, a Ball and a Tetraeder class, I'm assuming you want to make more classes). And if you add new classes, you'll have to change the code, which means you have to recompile.
You have to know what the derived classes are. You're the one who codes them, so you might as well also have a list of them. The best thing you can do about your program being flexible is using header files, which you already seem to be doing anyway.
As for creating an object from a string in a text file (while you know what the 3D object classes are), you can parse the string, read what kind of a shape it wants to make and then do something fairly simple such as this:
//shapeType - a string containing the type of the 3D object
Shape *newShape;
switch(shapeType) {
case "ball":
newShape = new Ball(...); // ... - parameters for the ball dimensions
break;
case "tetraeder":
newShape = new Tetraeder(...); // ... - parameters again
break;
default:
return -1;
}
//and now you can use newShape as you wish
Since my last question had too much code in it, I tried to make the simplest example of what I'm trying to do. Take this for example,..
#include <iostream>
using namespace std;
class String
{
public:
private:
};
class ClassTwo
{
public:
int memberVariable;
private:
};
class ClassOne
{
public:
ClassOne (ClassTwo&, String&);
~ClassOne();
private:
ClassTwo& classTwoReference;
String& stringReference;
};
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.memberVariable = 3;
}
ClassOne::~ClassOne()
{
}
int main()
{
String stringObject;
ClassTwo classTwoObject;
ClassOne classOneObject (classTwoObject, stringObject);
}
In JUCE, which is the API I'm using to code a VST Plugin, there is a string class that JUCE names "String". I'm not sure exactly what the constructor does, but you can use something like this to create a String object.
String newString("string");
The ClassTwo in my case, is the AudioProcessor class which has a public member variable that I can access from ClassOne like this.
two.memberVariable = 3;
The ClassOne in my case, is a custom Component(I named it PixelSlider) that I'm using in my GUI. It uses a slider listener to check the status of a slider and modify the member variable in ClassTwo(AudioProcessor). I can do this fine using the method above, but the issue is that I want to create as many ClassOne(PixelSlider) objects as I need. I want to pass them a String object that tells them what member variable of ClassTwo(AudioProcessor) to modify. Logically, this would be done by passing a reference to a String object with the same string value as the name of the ClassTwo member variable. Like this,...
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.(string) = 3;
}
This doesn't work in JUCE, but can anybody tell me a way to get this done without having to create a bunch of different classes almost exactly like ClassOne(PixelSlider) that modify different ClassTwo(AudioProcessor) member variables?
If I understand correctly, you're trying to bind a PixelSlider target to a member of AudioProcessor at runtime, which, as you've discovered, can't be done the way you suggest ( two.(string) = 3 ). One way of achieving this binding would be to use the command pattern (http://sourcemaking.com/design_patterns/command/cpp/2).
AudioProcessor could expose a collection of these command objects for each modifiable property ...
AudioProcessorCommand
AudioProcessor::GetCommandByName(String const& properyName) const
{
...
}
... which you can pass to the constructor of PixelSlider. Something along the lines of ...
PixelSlider::PixelSlider(AudioProcessorCommand& command)
: command_{command}
{
...
}
When the PixelSlider's value changes you would invoke the command ...
command_(this->value_);
Hey there fellow programmers, I'm having a big issue with this thing! I just want to create a class that inherits stuff from previous class, but the problem is that in both class I have constructors and the compiler just won't compile this simple code - It's telling me - 10.12.2012.3.cpp:28:3: error: no matching function for call to ‘Monitor::Monitor()’: Please Ignore the main fuction - It's not doing anything in particular, sine I can't get past this problem :/ Sorry for dumb question, but I couldn't find the specific answer PS: my first post here :)
#include <iostream>
#include <string.h>
using namespace std;
class Monitor
{
protected:
int sifra;
public:
Monitor (int sifra1)
{
sifra = sifra1;
}
};
class Prodaja : public Monitor
{
protected:
int monster;
public:
Prodaja (int monster1)
{
monster = monster1;
}
};
int main()
{
int sifra1;
string firma1, model1, dobavitelj1;
float nabava1, cena1;
return 0;
}
Monitor does not have a default constructor.
You have to invoke its constructor in the constructor of the derived class. That's because otherwise the Prodaja instance doesn't know how to construct its Monitor part.
So you need
Prodaja (int monster1): Monitor(monster1)
or to define a constructor of Monitor that takes no parameters (or has a default parameter).
How can I call a function and keep my constructor private? If I make the class static, I need to declare an object name which the compiler uses to call the constructor, which it cannot if the constructor is private (also the object would be extraneous). Here is the code I am attempting to use (it is not compilable):
I want to keep the constructor private because I will later be doing a lot of checks before adding an object, modifying previous objects when all submitted variables are not unique rather than creating new objects.
#include <iostream>
#include <fstream>
#include <regex>
#include <string>
#include <list>
#include <map>
using namespace std;
using namespace tr1;
class Referral
{
public:
string url;
map<string, int> keywords;
static bool submit(string url, string keyword, int occurrences)
{
//if(Referrals.all.size == 0){
// Referral(url, keyword, occurrences);
//}
}
private:
list<string> urls;
Referral(string url, string keyword, int occurrences)
{
url = url;
keywords[keyword] = occurrences;
Referrals.all.push_back(this);
}
};
struct All
{
list<Referral> all;
}Referrals;
int main()
{
Referral.submit("url", "keyword", 1);
}
What's wrong with having a private constructor and a static factory method?
class Example {
Example() { ... }
public:
static Example CreateExample() {
return Example();
}
};
Based on your main code I think what you're shooting for is a singleton, which would look something like:
class Referral
{
private:
Referral()
{
//...
}
public:
static Referral& instance()
{
static Referral instance_s;
return instance_s;
}
bool submit(string url, string keyword, int occurrences)
{
//...
}
};
Then your call in main would look like:
int main()
{
Referral::instance().submit("url", "keyword", 1);
}
Another possibility is that you're looking to keep a list of Referrals around, in which case you can use a struct and a list of them to accomplish what you're looking for:
struct Referral
{
Referral(string url, string keyword, int occurrences) :
url_m(url), keyword_m(keyword), occurrences_m(occurrences)
{ }
string url_m;
string keyword_m;
int occurrences_m;
};
typedef std::vector<Referral> ReferralSet;
Then your call in main would look like:
int main()
{
ReferralSet set;
set.push_back(Referral("url", "keyword", 1));
}
First, you need to make Submit a static function. Then you can just say
Referral::Submit( url, keyword, occurrences );
without creating a Referral instance.
Then, in your Submit function, you're only creating a temporary Referral object that disappears almost immediately. Probably what you want to do is create an instance dynamically with new. Depending on how you want to manage this, you may want to move the code pushing onto the list into Submit.
Lastly, I would make your list of Referral instances a static member variable rather than how you have it now.
(Also, passing those string arguments by reference would probably be a good idea.)
While the whole code has some smell around, you can make it work just by making slight changes that are unrelated to your question.
To make it compile, I have removed the regex include (I am not using a compiler with C++0x support) and the 'using namespace tr1'. Move the constructor implementation after the definition of the Referral global object. Change the . for a :: in the main function when you refer to a static method.
// changes...
//#include <regex>
...
//using namespace tr1;
...
class Referral {
...
Referral(string url, string keyword, int occurrences); // added ; moved the implementation bellow the Referrals variable definition
...
struct All {
...
} Referrals;
// added constructor implementation here (Referrals global must be defined before use):
Referral::Referral(string url, string keyword, int occurrences)
{
url = url;
keywords[keyword] = occurrences;
Referrals.all.push_back(*this); // added dereference, this is of type Referral*, not Referral
}
int main()
{
Referral::submit("url","keyword",1);
}
Now, from a design point of view the code has a stench to it. If really want to have a global list where you add your Referral objects, consider making it a private static attribute of the Referral class so that you can have a little more control over it (only methods in the Referral class could break the contents). Make all your attributes private and provide only accessors to the functionality that user code will need (read-only access can suffice in most cases). Use initialization lists in your constructors, and initialize all members there in the same order they appear in the class definition.
With all that fixed, it still has some smell to it. The static function creates an instance of the class but the constructor is the one that includes itself in the map (??) It would make a little more sense if the constructor did not interact with the map, and the submit() method would create the object and then include it in the list...
I think you might benefit from expressing what you intend to do, many people here will help you both with design choices and reasons for them.
I have a situation where I have an interface that defines how a certain class behaves in order to fill a certain role in my program, but at this point in time I'm not 100% sure how many classes I will write to fill that role. However, at the same time, I know that I want the user to be able to select, from a GUI combo/list box, which concrete class implementing the interface that they want to use to fill a certain role. I want the GUI to be able to enumerate all available classes, but I would prefer not to have to go back and change old code whenever I decide to implement a new class to fill that role (which may be months from now)
Some things I've considered:
using an enumeration
Pros:
I know how to do it
Cons
I will have to update update the enumeration when I add a new class
ugly to iterate through
using some kind of static list object in the interface, and adding a new element from within the definition file of the implementing class
Pros:
Wont have to change old code
Cons:
Not even sure if this is possible
Not sure what kind of information to store so that a factory method can choose the proper constructor ( maybe a map between a string and a function pointer that returns a pointer to an object of the interface )
I'm guessing this is a problem (or similar to a problem) that more experienced programmers have probably come across before (and often), and there is probably a common solution to this kind of problem, which is almost certainly better than anything I'm capable of coming up with. So, how do I do it?
(P.S. I searched, but all I found was this, and it's not the same: How do I enumerate all items that implement a generic interface?. It appears he already knows how to solve the problem I'm trying to figure out.)
Edit: I renamed the title to "How can I keep track of... " rather than just "How can I enumerate..." because the original question sounded like I was more interested in examining the runtime environment, where as what I'm really interested in is compile-time book-keeping.
Create a singleton where you can register your classes with a pointer to a creator function.
In the cpp files of the concrete classes you register each class.
Something like this:
class Interface;
typedef boost::function<Interface* ()> Creator;
class InterfaceRegistration
{
typedef map<string, Creator> CreatorMap;
public:
InterfaceRegistration& instance() {
static InterfaceRegistration interfaceRegistration;
return interfaceRegistration;
}
bool registerInterface( const string& name, Creator creator )
{
return (m_interfaces[name] = creator);
}
list<string> names() const
{
list<string> nameList;
transform(
m_interfaces.begin(), m_interfaces.end(),
back_inserter(nameList)
select1st<CreatorMap>::value_type>() );
}
Interface* create(cosnt string& name ) const
{
const CreatorMap::const_iterator it
= m_interfaces.find(name);
if( it!=m_interfaces.end() && (*it) )
{
return (*it)();
}
// throw exception ...
return 0;
}
private:
CreatorMap m_interfaces;
};
// in your concrete classes cpp files
namespace {
bool registerClassX = InterfaceRegistration::instance("ClassX", boost::lambda::new_ptr<ClassX>() );
}
ClassX::ClassX() : Interface()
{
//....
}
// in your concrete class Y cpp files
namespace {
bool registerClassY = InterfaceRegistration::instance("ClassY", boost::lambda::new_ptr<ClassY>() );
}
ClassY::ClassY() : Interface()
{
//....
}
I vaguely remember doing something similar to this many years ago. Your option (2) is pretty much what I did. In that case it was a std::map of std::string to std::typeinfo. In each, .cpp file I registered the class like this:
static dummy = registerClass (typeid (MyNewClass));
registerClass takes a type_info object and simply returns true. You have to initialize a variable to ensure that registerClass is called during startup time. Simply calling registerClass in the global namespace is an error. And making dummy static allow you to reuse the name across compilation units without a name collision.
I referred to this article to implement a self-registering class factory similar to the one described in TimW's answer, but it has the nice trick of using a templated factory proxy class to handle the object registration. Well worth a look :)
Self-Registering Objects in C++ -> http://www.ddj.com/184410633
Edit
Here's the test app I did (tidied up a little ;):
object_factory.h
#include <string>
#include <vector>
// Forward declare the base object class
class Object;
// Interface that the factory uses to communicate with the object proxies
class IObjectProxy {
public:
virtual Object* CreateObject() = 0;
virtual std::string GetObjectInfo() = 0;
};
// Object factory, retrieves object info from the global proxy objects
class ObjectFactory {
public:
static ObjectFactory& Instance() {
static ObjectFactory instance;
return instance;
}
// proxies add themselves to the factory here
void AddObject(IObjectProxy* object) {
objects_.push_back(object);
}
size_t NumberOfObjects() {
return objects_.size();
}
Object* CreateObject(size_t index) {
return objects_[index]->CreateObject();
}
std::string GetObjectInfo(size_t index) {
return objects_[index]->GetObjectInfo();
}
private:
std::vector<IObjectProxy*> objects_;
};
// This is the factory proxy template class
template<typename T>
class ObjectProxy : public IObjectProxy {
public:
ObjectProxy() {
ObjectFactory::Instance().AddObject(this);
}
Object* CreateObject() {
return new T;
}
virtual std::string GetObjectInfo() {
return T::TalkToMe();
};
};
objects.h
#include <iostream>
#include "object_factory.h"
// Base object class
class Object {
public:
virtual ~Object() {}
};
class ClassA : public Object {
public:
ClassA() { std::cout << "ClassA Constructor" << std::endl; }
~ClassA() { std::cout << "ClassA Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassA"; }
};
class ClassB : public Object {
public:
ClassB() { std::cout << "ClassB Constructor" << std::endl; }
~ClassB() { std::cout << "ClassB Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassB"; }
};
objects.cpp
#include "objects.h"
// Objects get registered here
ObjectProxy<ClassA> gClassAProxy;
ObjectProxy<ClassB> gClassBProxy;
main.cpp
#include "objects.h"
int main (int argc, char * const argv[]) {
ObjectFactory& factory = ObjectFactory::Instance();
for (int i = 0; i < factory.NumberOfObjects(); ++i) {
std::cout << factory.GetObjectInfo(i) << std::endl;
Object* object = factory.CreateObject(i);
delete object;
}
return 0;
}
output:
This is ClassA
ClassA Constructor
ClassA Destructor
This is ClassB
ClassB Constructor
ClassB Destructor
If you're on Windows, and using C++/CLI, this becomes fairly easy. The .NET framework provides this capability via reflection, and it works very cleanly in managed code.
In native C++, this gets a little bit trickier, as there's no simple way to query the library or application for runtime information. There are many frameworks that provide this (just look for IoC, DI, or plugin frameworks), but the simplest means of doing it yourself is to have some form of configuration which a factory method can use to register themselves, and return an implementation of your specific base class. You'd just need to implement loading a DLL, and registering the factory method - once you have that, it's fairly easy.
Something you can consider is an object counter. This way you don't need to change every place you allocate but just implementation definition. It's an alternative to the factory solution. Consider pros/cons.
An elegant way to do that is to use the CRTP : Curiously recurring template pattern.
The main example is such a counter :)
This way you just have to add in your concrete class implementation :
class X; // your interface
class MyConcreteX : public counter<X>
{
// whatever
};
Of course, it is not applicable if you use external implementations you do not master.
EDIT:
To handle the exact problem you need to have a counter that count only the first instance.
my 2 cents
There is no way to query the subclasses of a class in (native) C++.
How do you create the instances? Consider using a Factory Method allowing you to iterate over all subclasses you are working with. When you create an instance like this, it won't be possible to forget adding a new subclass later.