Export a class with std::string - c++

I know this subject has been covered and re-talked, but I still get stuck every time I need to do something like that, and the internet is full of different answers.
so I decided to simply ask how to deal with such situation once and for all.
Lets say I have the following class:
class PETS_EXPORT_API dog
{
public:
dog(std::string name):_name(name){}
~dog(){}
private:
std::string _name;
};
Obviously this code would generate a warning because I'm trying to export std::string. How do I solve such issue ?
thanks!

Alternative to Joe McGrath's answer:
If you really want your clients to have access to Dog public & protected interface, and does not make sense to have an abstract interface,
You could use the pImpl idiom, to hide the private interface.
Additionally you could export the string in the form of chars
Hide your original dog:
class Dog_Impl // your original class
{
public:
Dog_Impl(std::string name):_name(name){}
~Dog_Impl(){}
string::get_name();
private:
std::string _name;
};
Put this into your API:
class Dog_Impl; // fwd declaration
class PETS_EXPORT_API Dog {
public:
Dog(const char *name);
~Dog();
const char *get_name();
private:
Dog_Impl *pImpl;
};
The implementation should simply pass all public & protected interface to the pImpl:
Dog::Dog(const char *name)
{
pImpl = new Dog_Impl(name);
}
Dog::~Dog()
{
delete pImpl;
}
const char *Dog::get_name()
{
return pImpl->get_name().c_str();
}

You don't want to export the private members. Only the public interface. Make an abstract base class and export it.
struct DogInterface
{
virtual string IAmADog(void) = 0; // your public interface goes here
};
// Factory function that creates dogs
extern "C" PETS_EXPORT_API DogInterface* APIENTRY GetDog();
If you just want to export the string for access
__declspec(dllexport) const char* MyExportedString()
{
return myString.c_str()
}

Related

C++: how to make a group of derived classes be able to access private members of one class?

Suppose a class: Library
And we have a group of derived class from the base class LibraryCustomer, such as:
Kid, Parent, Student,
etc
In the class of Library, there are a group of (tons of) private members variables.
Since there are tons of private members in the class of Library, I do not want to use getter and setter which are tedious.
Plus the LibraryCustomer derived classes will often refer to those members. Getter and Setter are not convenient.
In order for those LibraryCustomers to access those private member in Library,
I need to claim those LibraryCustomers as friend classes in Library.
But since the derived classes keep growing, I do not want to add them one by one in the class Library.
Add the base class LibraryCustomer as friend in Library seems not to work.
So what is another better way?
[Update] I want to access tons of private member variables in the class of Library.
Since there are many, so I do not want to use getter and setter.
I hope the derived classes from LibraryCustomer can freely access those private member variables in the class of Library.
Provide a function in LibraryCustomer that accesses Library to get the data and provides that data to the classes derived from LibraryCustomer.
class Library
{
friend class LibraryCustomer;
private:
std::string name;
};
class LibraryCustomer
{
protected:
std::string getLibraryName(Library const& lib)
{
return lib.name;
}
};
class Kid : public LibraryCustomer
{
// Can use LibraryCustomer::getLibraryName() any where
// it needs to.
};
Having said that, it will be easier to provide access to the data from Library itself.
class Library
{
public:
std::string getName() const { return name; }
private:
std::string name;
};
Then, there won't be the need for the friend declaration and the wrapper function LibraryCustomer::getLibraryName().
EDIT
#MooingDuck has interesting suggestion. If you have to expose many such variables, it might be better to put them all in one class. Working code at http://coliru.stacked-crooked.com/a/2d647c3d290604e9.
#include <iostream>
#include <string>
class LibraryInterface {
public:
std::string name;
std::string name1;
std::string name2;
std::string name3;
std::string name4;
std::string name5;
std::string name6;
};
class Library : private LibraryInterface
{
public:
Library() {name="BOB";}
private:
LibraryInterface* getLibraryInterface() {return this;} //only LibraryCustomer can aquire the interface pointer
friend class LibraryCustomer;
};
class LibraryCustomer
{
protected:
LibraryInterface* getLibraryInterface(Library& lib) {return lib.getLibraryInterface();} //only things deriving from LibraryCustomer can aquire the interface pointer
};
class Kid : public LibraryCustomer
{
public:
void function(Library& lib) {
LibraryInterface* interface = getLibraryInterface(lib);
std::cout << interface->name;
}
};
int main() {
Library lib;
Kid k;
k.function(lib);
}

Properly extending a class in C++

with this code:
class Plant
{
public:
virtual std::string getPlantName();
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
};
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
private:
std::string _plantName;
};
and then:
#include "Carrot.hpp"
Carrot::Carrot()
{
}
Carrot::~Carrot() { }
std::string Carrot::getPlantName() { return _plantName; }
I am getting a link error:
Carrot.cpp:16:21: Out-of-line definition of 'getPlantName' does not match any declaration in 'Carrot'
So the goal here is to create a Plant class where other classes extend like class Carrot : public Plant
But, what I am not sure about is could I just inline the functionality in Plant so that I dont have to create these get and set functions in each class like Carrot or Peas, etc?
if I did:
inline virtual std::string getPlantName( return _plantName; );
would that work? I would then add std::string _PlantName; to class Plant and then when I create Carrot from Plant I get all the same functions and Carrot will have variables like _plantName, etc, correct?
So this would be:
class Plant
{
public:
inline virtual std::string getPlantName( return _plantName; );
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
private:
std::string _plantName;
};
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
};
#include "Carrot.hpp"
Carrot::Carrot()
{
setPlantName(CARROT::plantName);
}
Carrot::~Carrot() { }
If all objects of the Plant class should have a type and a name, both std::strings, you probably want those common members in the base class:
// Plant.hpp
class Plant
{
public:
Plant();
virtual ~Plant(); // virtual destructor!
virtual std::string getPlantName();
virtual void setPlantName(std::string s);
virtual std::string getPlantType();
virtual void setPlantType(std::string s);
protected:
std::string _plantName;
std::string _plantType;
};
// Plant.cpp
#include <Plant.hpp>
std::string Plant::getPlantName() { return _plantName; }
void Plant::setPlantName(std::string s) { _plantName = s; }
... same for type
When creating a derived class using class Carrot : public Plant, that class will have the same data members and the same functions. You would also have the ability to override them if needed (thanks to the virtual keyword, derived classes' implementations will be called when using a Plant pointer to a Carrot object).
Note that if you want to make sure never to instansiate a Plant object, you should make any non-common functions (like a DoSomethingTypeSpecific() that a Carrot or a Flower would do differently) pure virtual and by that creating an abstract base class. All base classes would then have to implement those functions.
Inlining here does not make a real difference, it's just a matter of defining the functions in the header or in a separate .cpp file. Generally, it's a good idea to keep the implementation in a separate file but these small setters and getters could easily be inlined if you wanted to.
You could correct the error by adding the method to the class declaration:
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
virtual std::string getPlantName();
private:
std::string _plantName;
};
Or, if all plants have names, you could define the method in the Plant class instead (likely in in plant.cpp). In fact, you have to define it unless you declare it to be pure virtual.
You need to declare the function.
class Carrot : public Plant
{
public:
Carrot();
~Carrot();
std::string getPlantName(); //Add this
private:
std::string _plantName;
};
A couple of notes:
It isn't strictly necessary for Carrot::getPlantName to be virtual, although many C++ developers consider it good form. I personally prefer to only use virtuals in abstract base classes, and use none in concrete classes
You probabally need to add virtual ~Plant() {} to the Plant class. You almost always want classes with virtual methods to also have virtual destructors.

C++ Design pattern for separate accessor/mutator interfaces

I have a data structure "Person"
struct Person
{
protected:
string name;
int age;
string address;
...
}
I want to create "views" around this structure to separate out access to different member variables:
class PersonRead: public Person
{
public:
string getName() {..}
int getAge() {...}
...
}
class PersonUpdate: public Person
{
public:
void setAddress( string address_ ) {...}
void setAge( int age_ ) {...}
...
}
I use this to only expose those methods/variables which are really required:
int main()
{
...
writePersonDataToFile ( (PersonRead) personObj );
updatePersonData ( (PersonUpdate) personObj);
...
}
Though the above code serves my purpose, there are several issues including:
The public inheritence here is not exactly an 'is-a' relationship
I need to derive IndianPerson from Person, and all the corresponding interfaces. This leads to bad diamond pattern:
struct IndianPerson: public Person {};
class IndianPersonRead: public IndianPerson, public PersonRead {}; //Person Class common, Diamond pattern here!
Is there a name for such a design pattern? What are better ways to implement this pattern? I have a feeling Policy classes might help, but cant figure out how to implement this
Any examples would be great help
For your scenario this might seem like overkill but, if you want fine grained control over which classes can call different methods on your class the c++ client-attorney idiom idiom might be appropriate.
For a detailed description of this idiom see http://drdobbs.com/184402053
Here is a rough example (note: this has not been compiled, although it is based on production code I am currently using):
class Person
{
public:
/// constructor destructor etc:
private:
string getName() { return name; }
public:
/// Writer Attourney that access to allows class PersonReader access
/// to getXXX functions
class ReaderAttorney
{
private:
/// Add additional reader member functions...
static string readName( Person& p )
{
return p.getName();
}
// Make any classes that shuold be allowde read access friends of the
// attorney here
friend class PersonReader;
};
/// Writer Attourney that access to allows class PersonWriter access
/// to setXXX functions
class WriterAttorney
{
private:
/// Add additiona reader member functions...
static string setName( Person& p, const string& newName )
{
p.setName( newName );
}
friend class PersonWriter;
};
private:
string name;
int age;
string address;
};
This can be used as follows:
void PersonWriter::setPersonDetails( const string& name, int age .... )
{
// PersonWriter is a frend of WriterAttorney and is granted access
Person::WriterAttorney::setName( name );
Person::WriterAttorney::setName( age );
// Note this will fail, since PersonWriter is not a friend of
// ReaderAttorney, ergo it is not granted read permission:
Person::ReaderAttorney::readName();
}
I think that your approach is not correct at all: PersonRead and PersonUpdate are not Persons. They read and modify Person data but are not really Person.
In the same way, IndianPersonRead and IndianPersonUpdate are not an IndianPerson.
I separate this relationship in following:
PersonRead use Person
PersonUpdate use Person
IndianPerson inherits from Person: is a Person
IndianPersonRead inherits from PersonRead and use IndianPerson
IndianPersonUpdate inherits from PersonUpdate and use IndianPerson
I show an example of my apporach:
#include <string>
#include <iostream>
using namespace std;
struct Person
{
string getname() const { return name; }
string getaddress() const { return address; }
void setaddress(const string & address_) { address = address_; }
void setname(const string & name_) { name = name_; }
protected:
string name;
int age;
string address;
};
class PersonRead
{
public:
string getname(const Person & p) { return p.getname(); }
};
class PersonUpdate
{
public:
void setAddress(Person & p, const string & address_ ) {p.setaddress(address_); }
void setname(Person & p, const string & name_ ) {p.setname(name_); }
};
struct IndianPerson : public Person
{
string gettribe() const { return tribe; }
void settribe(const string & tribe_) { tribe = tribe_; }
protected:
string tribe;
};
struct IndianPersonRead : public PersonRead
{
public:
string gettribe(const IndianPerson & p) const { return p.gettribe(); }
};
struct IndianPersonUpdate : public PersonUpdate
{
public:
void settribe(IndianPerson & p, const string & t) { p.settribe(t); }
};
int main(int argc, char **argv)
{
IndianPerson ip;
IndianPersonUpdate ipU;
IndianPersonRead ipR;
ipU.settribe(ip, "Cheroki");
ipU.setname(ip, "Charly");
cout << ipR.getname(ip) << " : " << ipR.gettribe(ip) << endl;
}
First of all I will agree with the Tio's point of view PersonUpdate is not a Person so there is a wrong inheritance usage. Also I believe that you need to make your classes with target to represent the real world so classes like PersonUpdate are wrong because they represent the action and not the object.
In your case one solution could be to use the visitor design pattern, so the Person could accept a especially designed IPersonStream interface in order to perform the serialization in classes which will implement this interface.
Person stream will accept the persons attributes on it or for good the Person's memento take a look on memento design pattern, and serialize it to xml or whatever you want.
I don't have a design pattern name, but to resolve your concerns, I would swap the inheritance relation and let Person inherit from the PersonReader and PersonWriter interfaces. This way, objects that must only read from Person use the PersonReader interface and as such promises to not change it.
By making every member of Person private, you can even make sure that Person is not accessed in another way, but then every class that inherits from Person should have these members private.

C++ Header file that declares a class and methods but not members?

Is it possible to make a C++ header file (.h) that declares a class, and its public methods, but does not define the private members in that class? I found a few pages that say you should declare the class and all its members in the header file, then define the methods separately in you cpp file. I ask because I want to have a class that is defined in a Win32 DLL, and I want it to be properly encapsulated: the internal implementation of that class might change, including its members, but these changes should not affect code that uses the class.
I guess that if I had this, then it would make it impossible for the compiler to know the size of my objects ahead of time. But that should be fine, as long as the compiler is smart enough to use the constructor and just pass around pointers to the location in memory where my object is stored, and never let me run "sizeof(MyClass)".
Update: Thanks to everyone who answered! It seems like the pimpl idiom is a good way to achieve what I was talking about. I'm going to do something similar:
My Win32 DLL file will have a bunch of separate functions like this:
void * __stdcall DogCreate();
int __stdcall DogGetWeight(void * this);
void __stdcall DogSetWeight(void * this, int weight);
This is the typical way the Microsoft writes their DLL files so I think there is probably good reason for it.
But I want to take advantage of the nice syntax C++ has for classes, so I'll write a wrapper class to wrap up all of these functions. It will have one member, which will be "void * pimpl". This wrapper class will be so simple that I might as well just declare it AND define it in the header file. But this wrapper class really has no purposes other than making the C++ code look pretty as far as I can tell.
I think what you are looking for is something called the "pimpl idiom". To understand how this works, you need to understand that in C++ you can forward declare something like so.
class CWidget; // Widget will exist sometime in the future
CWidget* aWidget; // An address (integer) to something that
// isn't defined *yet*
// later on define CWidget to be something concrete
class CWidget
{
// methods and such
};
So to forward declare means to promise to fully declare a type later. Its saying "there will be this thing called a CWidget, I promise. I'll tell you more about it later.".
The rules of forward declaration say that you can define a pointer or a reference to something that has been forward declared. This is because pointers and references are really just addresses-a number where this yet-to-be-defined thing will be. Being able to declare a pointer to something without fully declaring it is convenient for a lot of reasons.
Its useful here because you can use this to hide some of the internals of a class using the "pimpl" method. Pimpl means "pointer to implementation". So instead of "widget" you have a class that is the actual implementation. The class you are declaring in your header is just a pass-through to the CImpl class. Here's how it works:
// Thing.h
class CThing
{
public:
// CThings methods and constructors...
CThing();
void DoSomething();
int GetSomething();
~CThing();
private:
// CThing store's a pointer to some implementation class to
// be defined later
class CImpl; // forward declaration to CImpl
CImpl* m_pimpl; // pointer to my implementation
};
Thing.cpp has CThing's methods defined as pass-throughs to the impl:
// Fully define Impl
class CThing::CImpl
{
private:
// all variables
public:
// methods inlined
CImpl()
{
// constructor
}
void DoSomething()
{
// actual code that does something
}
//etc for all methods
};
// CThing methods are just pass-throughs
CThing::CThing() : m_pimpl(new CThing::CImpl());
{
}
CThing::~CThing()
{
delete m_pimpl;
}
int CThing::GetSomething()
{
return m_pimpl->GetSomething();
}
void CThing::DoSomething()
{
m_impl->DoSomething();
}
tada! You've hidden all the details in your cpp and your header file is a very tidy list of methods. Its a great thing. The only thing you might see different from the template above is that people may use boost::shared_ptr<> or other smart pointer for the impl. Something that deletes itself.
Also, keep in mind this method comes with some annoyances. Debugging can be a tad bit annoying (extra level of redirection to step through). Its also a lot of overhead for creating a class. If you do this for every class, you'll get tired of all the typing :).
Use pimpl idiom.
The pimpl idiom adds a void* private data member to your class, and this is a useful technique if you need something quick & dirty. It has its drawbacks however. Main among those is it makes it difficult to use polymorphism on the abstract type. Sometimes you might want an abstract base class and subclasses of that base class, collect pointers to all the different types in a vector and call methods on them. In addition, if the purpose of the pimpl idiom is to hide the implementation details of the class then it only almost succeeds: the pointer itself is an implementation detail. An opaque implementation detail, perhaps. But an implementation detail nonetheless.
An alternative to the pimpl idiom exists which can be used to remove all of the implementation details from the interface while providing a base type that can be used polymorphically, if needed.
In your DLL's header file (the one #included by client code) create an abstract class with only public methods and concepts which dictate how the class is to be instantiated (eg, public factory methods & clone methods):
kennel.h
/****************************************************************
***
*** The declaration of the kennel namespace & its members
*** would typically be in a header file.
***/
// Provide an abstract interface class which clients will have pointers to.
// Do not permit client code to instantiate this class directly.
namespace kennel
{
class Animal
{
public:
// factory method
static Animal* createDog(); // factory method
static Animal* createCat(); // factory method
virtual Animal* clone() const = 0; // creates a duplicate object
virtual string speak() const = 0; // says something this animal might say
virtual unsigned long serialNumber() const = 0; // returns a bit of state data
virtual string name() const = 0; // retuyrns this animal's name
virtual string type() const = 0; // returns the type of animal this is
virtual ~Animal() {}; // ensures the correct subclass' dtor is called when deleteing an Animal*
};
};
...Animal is an abstract base class and so cannot be instantiated; no private ctor needs to be declared. The presence of the virtual dtor ensures that if someone deletes an Animal*, the proper subclass' dtor will also be called.
In order to implement different subclasses of the base type (eg dogs & cats), you would declare implementation-level classes in your DLL. These classes derive ultimately from the abstract base class you declared in your header file, and the factory methods would actually instantiate one of these subclasses.
dll.cpp:
/****************************************************************
***
*** The code that follows implements the interface
*** declared above, and would typically be in a cc
*** file.
***/
// Implementation of the Animal abstract interface
// this implementation includes several features
// found in real code:
// Each animal type has it's own properties/behavior (speak)
// Each instance has it's own member data (name)
// All Animals share some common properties/data (serial number)
//
namespace
{
// AnimalImpl provides properties & data that are shared by
// all Animals (serial number, clone)
class AnimalImpl : public kennel::Animal
{
public:
unsigned long serialNumber() const;
string type() const;
protected:
AnimalImpl();
AnimalImpl(const AnimalImpl& rhs);
virtual ~AnimalImpl();
private:
unsigned long serial_; // each Animal has its own serial number
static unsigned long lastSerial_; // this increments every time an AnimalImpl is created
};
class Dog : public AnimalImpl
{
public:
kennel::Animal* clone() const { Dog* copy = new Dog(*this); return copy;}
std::string speak() const { return "Woof!"; }
std::string name() const { return name_; }
Dog(const char* name) : name_(name) {};
virtual ~Dog() { cout << type() << " #" << serialNumber() << " is napping..." << endl; }
protected:
Dog(const Dog& rhs) : AnimalImpl(rhs), name_(rhs.name_) {};
private:
std::string name_;
};
class Cat : public AnimalImpl
{
public:
kennel::Animal* clone() const { Cat* copy = new Cat(*this); return copy;}
std::string speak() const { return "Meow!"; }
std::string name() const { return name_; }
Cat(const char* name) : name_(name) {};
virtual ~Cat() { cout << type() << " #" << serialNumber() << " escaped!" << endl; }
protected:
Cat(const Cat& rhs) : AnimalImpl(rhs), name_(rhs.name_) {};
private:
std::string name_;
};
};
unsigned long AnimalImpl::lastSerial_ = 0;
// Implementation of interface-level functions
// In this case, just the factory functions.
kennel::Animal* kennel::Animal::createDog()
{
static const char* name [] = {"Kita", "Duffy", "Fido", "Bowser", "Spot", "Snoopy", "Smkoky"};
static const size_t numNames = sizeof(name)/sizeof(name[0]);
size_t ix = rand()/(RAND_MAX/numNames);
Dog* ret = new Dog(name[ix]);
return ret;
}
kennel::Animal* kennel::Animal::createCat()
{
static const char* name [] = {"Murpyhy", "Jasmine", "Spike", "Heathcliff", "Jerry", "Garfield"};
static const size_t numNames = sizeof(name)/sizeof(name[0]);
size_t ix = rand()/(RAND_MAX/numNames);
Cat* ret = new Cat(name[ix]);
return ret;
}
// Implementation of base implementation class
AnimalImpl::AnimalImpl()
: serial_(++lastSerial_)
{
};
AnimalImpl::AnimalImpl(const AnimalImpl& rhs)
: serial_(rhs.serial_)
{
};
AnimalImpl::~AnimalImpl()
{
};
unsigned long AnimalImpl::serialNumber() const
{
return serial_;
}
string AnimalImpl::type() const
{
if( dynamic_cast<const Dog*>(this) )
return "Dog";
if( dynamic_cast<const Cat*>(this) )
return "Cat";
else
return "Alien";
}
Now you have the interface defined in the header & the implementation details completely seperated out where client code can't see it at all. You would use this by calling methods declared in your header file from code that links to your DLL. Here's a sample driver:
main.cpp:
std::string dump(const kennel::Animal* animal)
{
stringstream ss;
ss << animal->type() << " #" << animal->serialNumber() << " says '" << animal->speak() << "'" << endl;
return ss.str();
}
template<class T> void del_ptr(T* p)
{
delete p;
}
int main()
{
srand((unsigned) time(0));
// start up a new farm
typedef vector<kennel::Animal*> Animals;
Animals farm;
// add 20 animals to the farm
for( size_t n = 0; n < 20; ++n )
{
bool makeDog = rand()/(RAND_MAX/2) != 0;
if( makeDog )
farm.push_back(kennel::Animal::createDog());
else
farm.push_back(kennel::Animal::createCat());
}
// list all the animals in the farm to the console
transform(farm.begin(), farm.end(), ostream_iterator<string>(cout, ""), dump);
// deallocate all the animals in the farm
for_each( farm.begin(), farm.end(), del_ptr<kennel::Animal>);
return 0;
}
Google "pimple idiom" or "handle C++".
Yes, this can be a desireable thing to do. One easy way is to make the implementation class derive from the class defined in the header.
The downside is that the compiler won't know how to construct your class, so you'll need some kind of factory method to get instances of the class. It will be impossible to have local instances on the stack.
You have to declare all members in the header so the compiler knows how large is the object and so on.
But you can solve this by using an interface:
ext.h:
class ExtClass
{
public:
virtual void func1(int xy) = 0;
virtual int func2(XYClass &param) = 0;
};
int.h:
class ExtClassImpl : public ExtClass
{
public:
void func1(int xy);
int func2(XYClass&param);
};
int.cpp:
void ExtClassImpl::func1(int xy)
{
...
}
int ExtClassImpl::func2(XYClass&param)
{
...
}
Is it possible to make a C++ header
file (.h) that declares a class, and
its public methods, but does not
declare the private members in that
class?
The most nearest answer is PIMPL idiom.
Refer this The Fast Pimpl Idiom from Herb Sutter.
IMO Pimpl is really useful during initial stages of development where your header file is going to change many times. Pimpl has its cost due to its allocation\deallocation of internal object on heap.
Check out the class The Handle-Body Idiom in C++

How to design a simple C++ object factory?

In my application, there are 10-20 classes that are instantiated once[*]. Here's an example:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
Instances of the classes are contained in one object:
class TheManager {
public:
virtual SomeManagerClass* someManagerClass() const;
virtual SomeOtherManager* someOtherManager() const;
/** More objects... up to 10-20 */
};
Currently TheManager uses the new operator in order to create objects.
My intention is to be able to replace, using plugins, the SomeManagerClass (or any other class) implementation with another one. In order to replace the implementation, 2 steps are needed:
Define a class DerivedSomeManagerClass, which inherits SomeManagerClass [plugin]
Create the new class (DerivedSomeManagerClass) instead of the default (SomeManagerClass) [application]
I guess I need some kind of object factory, but it should be fairly simple since there's always only one type to create (the default implementation or the user implementation).
Any idea about how to design a simple factory like I just described? Consider the fact that there might be more classes in the future, so it should be easy to extend.
[*] I don't care if it happens more than once.
Edit: Please note that there are more than two objects that are contained in TheManager.
Assuming a class (plugin1) which inherits from SomeManagerClass, you need a class hierarchy to build your types:
class factory
{
public:
virtual SomeManagerClass* create() = 0;
};
class plugin1_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin1(); }
};
Then you can assign those factories to a std::map, where they are bound to strings
std::map<string, factory*> factory_map;
...
factory_map["plugin1"] = new plugin1_factory();
Finally your TheManager just needs to know the name of the plugin (as string) and can return an object of type SomeManagerClass with just one line of code:
SomeManagerClass* obj = factory_map[plugin_name]->create();
EDIT: If you don't like to have one plugin factory class for each plugin, you could modify the previous pattern with this:
template <class plugin_type>
class plugin_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin_type(); }
};
factory_map["plugin1"] = new plugin_factory<plugin1>();
I think this is a much better solution. Moreover the 'plugin_factory' class could add itself to the 'factory_map' if you pass costructor the string.
I think there are two separate problems here.
One problem is: how does TheManager name the class that it has to create? It must keep some kind of pointer to "a way to create the class". Possible solutions are:
keeping a separate pointer for each kind of class, with a way to set it, but you already said that you don't like this as it violates the DRY principle
keeping some sort of table where the key is an enum or a string; in this case the setter is a single function with parameters (of course if the key is an enum you can use a vector instead of a map)
The other problem is: what is this "way to create a class"? Unfortunately we can't store pointers to constructors directly, but we can:
create, as others have pointed out, a factory for each class
just add a static "create" function for each class; if they keep a consistent signature, you can just use their pointers to functions
Templates can help in avoiding unnecessary code duplication in both cases.
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns
I'd create a "base" factory that has virtual methods for creation of all the basic managers, and let the "meta manager" (TheManager in your question) take a pointer to the base factory as a constructor parameter.
I'm assuming that the "factory" can customize the instances of CXYZWManager by deriving from them, but alternatively the constructor of CXYZWManager could take different arguments in the "custom" factory.
A lengthy code example that outputs "CSomeManager" and "CDerivedFromSomeManager":
#include <iostream>
//--------------------------------------------------------------------------------
class CSomeManager
{
public:
virtual const char * ShoutOut() { return "CSomeManager";}
};
//--------------------------------------------------------------------------------
class COtherManager
{
};
//--------------------------------------------------------------------------------
class TheManagerFactory
{
public:
// Non-static, non-const to allow polymorphism-abuse
virtual CSomeManager *CreateSomeManager() { return new CSomeManager(); }
virtual COtherManager *CreateOtherManager() { return new COtherManager(); }
};
//--------------------------------------------------------------------------------
class CDerivedFromSomeManager : public CSomeManager
{
public:
virtual const char * ShoutOut() { return "CDerivedFromSomeManager";}
};
//--------------------------------------------------------------------------------
class TheCustomManagerFactory : public TheManagerFactory
{
public:
virtual CDerivedFromSomeManager *CreateSomeManager() { return new CDerivedFromSomeManager(); }
};
//--------------------------------------------------------------------------------
class CMetaManager
{
public:
CMetaManager(TheManagerFactory *ip_factory)
: mp_some_manager(ip_factory->CreateSomeManager()),
mp_other_manager(ip_factory->CreateOtherManager())
{}
CSomeManager *GetSomeManager() { return mp_some_manager; }
COtherManager *GetOtherManager() { return mp_other_manager; }
private:
CSomeManager *mp_some_manager;
COtherManager *mp_other_manager;
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
TheManagerFactory standard_factory;
TheCustomManagerFactory custom_factory;
CMetaManager meta_manager_1(&standard_factory);
CMetaManager meta_manager_2(&custom_factory);
std::cout << meta_manager_1.GetSomeManager()->ShoutOut() << "\n";
std::cout << meta_manager_2.GetSomeManager()->ShoutOut() << "\n";
return 0;
}
Here's the solution I thought of, it's not the best one but maybe it will help to think of better solutions:
For each class there would be a creator class:
class SomeManagerClassCreator {
public:
virtual SomeManagerClass* create(SomeOtherManager* someOtherManager) {
return new SomeManagerClass(someOtherManager);
}
};
Then, the creators will be gathered in one class:
class SomeManagerClassCreator;
class SomeOtherManagerCreator;
class TheCreator {
public:
void setSomeManagerClassCreator(SomeManagerClassCreator*);
SomeManagerClassCreator* someManagerClassCreator() const;
void setSomeOtherManagerCreator(SomeOtherManagerCreator*);
SomeOtherManagerCreator* someOtherManagerCreator() const;
private:
SomeManagerClassCreator* m_someManagerClassCreator;
SomeOtherManagerCreator* m_someOtherManagerCreator;
};
And TheManager will be created with TheCreator for internal creation:
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
The problem with this solution is that it violates DRY - for each class creator I would have to write setter/getter in TheCreator.
This seems like it would be a lot simpler with function templating as opposed to an Abstract Factory pattern
class ManagerFactory
{
public:
template <typename T> static BaseManager * getManager() { return new T();}
};
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
If you want to get them via a string, you can create a standard map from strings to function pointers. Here is an implementation that works:
#include <map>
#include <string>
class BaseManager
{
public:
virtual void doSomething() = 0;
};
class DerivedManager1 : public BaseManager
{
public:
virtual void doSomething() {};
};
class DerivedManager2 : public BaseManager
{
public:
virtual void doSomething() {};
};
class ManagerFactory
{
public:
typedef BaseManager * (*GetFunction)();
typedef std::map<std::wstring, GetFunction> ManagerFunctionMap;
private:
static ManagerFunctionMap _managers;
public:
template <typename T> static BaseManager * getManager() { return new T();}
template <typename T> static void registerManager(const std::wstring& name)
{
_managers[name] = ManagerFactory::template getManager<T>;
}
static BaseManager * getManagerByName(const std::wstring& name)
{
if(_managers.count(name))
{
return _managers[name]();
}
return NULL;
}
};
// the static map needs to be initialized outside the class
ManagerFactory::ManagerFunctionMap ManagerFactory::_managers;
int _tmain(int argc, _TCHAR* argv[])
{
// you can get with the templated function
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
manager1->doSomething();
// or by registering with a string
ManagerFactory::template registerManager<DerivedManager1>(L"Derived1");
ManagerFactory::template registerManager<DerivedManager2>(L"Derived2");
// and getting them
BaseManager * manager2 = ManagerFactory::getManagerByName(L"Derived2");
manager2->doSomething();
BaseManager * manager3 = ManagerFactory::getManagerByName(L"Derived1");
manager3->doSomething();
return 0;
}
EDIT: In reading the other answers I realized that this is very similar to Dave Van den Eynde's FactorySystem solution, but I'm using a function template pointer instead of instantiating templated factory classes. I think my solution is a little more lightweight. Due to static functions, the only object that gets instantiated is the map itself. If you need the factory to perform other functions (DestroyManager, etc.), I think his solution is more extensible.
You could implement an object factory with static methods that return an instance of a Manager-Class. In the factory you could create a method for the default type of manager and a method for any type of manager which you give an argument representing the type of the Manager-Class (say with an enum). This last method should return an Interface rather than a Class.
Edit: I'll try to give some code, but mind that my C++ times are quite a while back and I'm doing only Java and some scripting for the time being.
class Manager { // aka Interface
public: virtual void someMethod() = 0;
};
class Manager1 : public Manager {
void someMethod() { return null; }
};
class Manager2 : public Manager {
void someMethod() { return null; }
};
enum ManagerTypes {
Manager1, Manager2
};
class ManagerFactory {
public static Manager* createManager(ManagerTypes type) {
Manager* result = null;
switch (type) {
case Manager1:
result = new Manager1();
break;
case Manager2:
result = new Manager2();
break;
default:
// Do whatever error logging you want
break;
}
return result;
}
};
Now you should be able to call the Factory via (if you've been able to make the code sample work):
Manager* manager = ManagerFactory.createManager(ManagerTypes.Manager1);
I would use templates like this as I can't see the point of factories classes:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
class TheBaseManager {
public:
//
};
template <class ManagerClassOne, class ManagerClassOther>
class SpecialManager : public TheBaseManager {
public:
virtual ManagerClassOne* someManagerClass() const;
virtual ManagerClassOther* someOtherManager() const;
};
TheBaseManager* ourManager = new SpecialManager<SomeManagerClass,SomeOtherManager>;
You should take a look at the tutorial at
http://downloads.sourceforge.net/papafactory/PapaFactory20080622.pdf?use_mirror=fastbull
It contains a great tutorial on implementing an Abstract factory in C++ and the source code that comes with it is also very robust
Chris
Mh I don't understand a hundred percent, and I am not really into factory stuff from books and articles.
If all your managers share a similar interface you could derive from a base class, and use this base class in your program.
Depending on where the decision which class will be created will be made, you have to use an identifier for creation (as stated above) or handle the decision which manager to instantiate internally.
Another way would be to implement it "policy" like by using templates. So that You ManagerClass::create() returns a specific SomeOtherManagerWhatever instance. This would lay the decision which manager to make in the code which uses your Manager - Maye this is not intended.
Or that way:
template<class MemoryManagment>
class MyAwesomeClass
{
MemoryManagment m_memoryManager;
};
(or something like that)
With this construct you can easily use other managers by only changing the instantiation of MyAwesomeClass.
Also A class for this purpose might be a little over the top. In your case a factory function would do I guess. Well it's more a question of personal preference.
If you plan on supporting plugins that are dynamically linked, your program will need to provide a stable ABI (Application Binary Interface), that means that you cannot use C++ as your main interface as C++ has no standard ABI.
If you want plugins to implement an interface you define yourself, you will have to provide the header file of the interface to plugin programmer and standardize on a very simple C interface in order to create and delete the object.
You cannot provide a dynamic library that will allow you to "new" the plugin class as-is. That is why you need to standardize on a C interface in order to create the object. Using the C++ object is then possible as long as none of your arguments use possibly incompatible types, like STL containers. You will not be able to use a vector returned by another library, because you cannot ensure that their STL implementation is the same as yours.
Manager.h
class Manager
{
public:
virtual void doSomething() = 0;
virtual int doSomethingElse() = 0;
}
extern "C" {
Manager* newManager();
void deleteManager(Manager*);
}
PluginManager.h
#include "Manager.h"
class PluginManager : public Manager
{
public:
PluginManager();
virtual ~PluginManager();
public:
virtual void doSomething();
virtual int doSomethingElse();
}
PluginManager.cpp
#include "PluginManager.h"
Manager* newManager()
{
return new PluginManager();
}
void deleteManager(Manager* pManager)
{
delete pManager;
}
PluginManager::PluginManager()
{
// ...
}
PluginManager::~PluginManager()
{
// ...
}
void PluginManager::doSomething()
{
// ...
}
int PluginManager::doSomethingElse()
{
// ...
}
You didnt talk about TheManager. It looks like you want that to control which class is being used? or maybe you trying to chain them together?
It sounds like you need a abstract base class and a pointer to the currently used class. If you wish to chain you can do it in both abstract class and themanager class. If abstract class, add a member to the next class in chain, if themanager then sort it in order you which to use in a list. You'll need a way to add classes so you'll need an addMe() in themanager. It sounds like you know what your doing so w/e you choose should be right. A list with an addMe func is my recommendation and if you want only 1 active class then a function in TheManager deciding it would be good.
This maybe heavier than you need, but it sounds like you are trying to make a frame work class that supports plugins.
I would break it up into to 3 sections.
1) The FrameWork class would own the plugins.
This class is responsable for publishing interfaces supplied by the plugins.
2) A PlugIn class would own the componets that do the work.
This class is responsable for registering the exported interfaces, and binding the imported interfaces to the components.
3) The third section, the componets are the suppliers and consumers of the interfaces.
To make things extensible, getting things up and running might be broke up into stages.
Create everything.
Wire everything up.
Start everything.
To break things down.
Stop everything.
Destroy everything.
class IFrameWork {
public:
virtual ~IFrameWork() {}
virtual void RegisterInterface( const char*, void* ) = 0;
virtual void* GetInterface( const char* name ) = 0;
};
class IPlugIn {
public:
virtual ~IPlugIn() {}
virtual void BindInterfaces( IFrameWork* frameWork ) {};
virtual void Start() {};
virtual void Stop() {};
};
struct SamplePlugin :public IPlugIn {
ILogger* logger;
Component1 component1;
WebServer webServer;
public:
SamplePlugin( IFrameWork* frameWork )
:logger( (ILogger*)frameWork->GetInterface( "ILogger" ) ), //assumes the 'System' plugin exposes this
component1(),
webServer( component1 )
{
logger->Log( "MyPlugin Ctor()" );
frameWork->RegisterInterface( "ICustomerManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IVendorManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IAccountingManager", dynamic_cast( &webServer ) );
}
virtual void BindInterfaces( IFrameWork* frameWork ) {
logger->Log( "MyPlugin BindInterfaces()" );
IProductManager* productManager( static_cast( frameWork->GetInterface( "IProductManager" ) ) );
IShippingManager* shippingManager( static_cast( frameWork->GetInterface( "IShippingManager" ) ) );
component1.BindInterfaces( logger, productManager );
webServer.BindInterfaces( logger, productManager, shippingManager );
}
virtual void Start() {
logger->Log( "MyPlugin Start()" );
webServer.Start();
}
virtual void Stop() {
logger->Log( "MyPlugin Stop()" );
webServer.Stop();
}
};
class FrameWork :public IFrameWork {
vector plugIns;
map interfaces;
public:
virtual void RegisterInterface( const char* name, void* itfc ) {
interfaces[ name ] = itfc;
}
virtual void* GetInterface( const char* name ) {
return interfaces[ name ];
}
FrameWork() {
//Only interfaces in 'SystemPlugin' can be used by all methods of the other plugins
plugIns.push_back( new SystemPlugin( this ) );
plugIns.push_back( new SamplePlugin( this ) );
//add other plugIns here
for_each( plugIns.begin(), plugIns.end(), bind2nd( mem_fun( &IPlugIn::BindInterfaces ), this ) );
for_each( plugIns.begin(), plugIns.end(), mem_fun( &IPlugIn::Start ) );
}
~FrameWork() {
for_each( plugIns.rbegin(), plugIns.rend(), mem_fun( &IPlugIn::Stop ) );
for_each( plugIns.rbegin(), plugIns.rend(), Delete() );
}
};
Here's a minimal factory pattern implementation that I came up with in about 15 minutes. We use a similar one that uses more advanced base classes.
#include "stdafx.h"
#include <map>
#include <string>
class BaseClass
{
public:
virtual ~BaseClass() { }
virtual void Test() = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class DerivedClass2 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class IFactory
{
public:
virtual BaseClass* CreateNew() const = 0;
};
template <typename T>
class Factory : public IFactory
{
public:
T* CreateNew() const { return new T(); }
};
class FactorySystem
{
private:
typedef std::map<std::wstring, IFactory*> FactoryMap;
FactoryMap m_factories;
public:
~FactorySystem()
{
FactoryMap::const_iterator map_item = m_factories.begin();
for (; map_item != m_factories.end(); ++map_item) delete map_item->second;
m_factories.clear();
}
template <typename T>
void AddFactory(const std::wstring& name)
{
delete m_factories[name]; // Delete previous one, if it exists.
m_factories[name] = new Factory<T>();
}
BaseClass* CreateNew(const std::wstring& name) const
{
FactoryMap::const_iterator found = m_factories.find(name);
if (found != m_factories.end())
return found->second->CreateNew();
else
return NULL; // or throw an exception, depending on how you want to handle it.
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FactorySystem system;
system.AddFactory<DerivedClass1>(L"derived1");
system.AddFactory<DerivedClass2>(L"derived2");
BaseClass* b1 = system.CreateNew(L"derived1");
b1->Test();
delete b1;
BaseClass* b2 = system.CreateNew(L"derived2");
b2->Test();
delete b2;
return 0;
}
Just copy & paste over an initial Win32 console app in VS2005/2008. I like to point out something:
You don't need to create a concrete factory for every class. A template will do that for you.
I like to place the entire factory pattern in its own class, so that you don't need to worry about creating factory objects and deleting them. You simply register your classes, a factory class gets created by the compiler and a factory object gets created by the pattern. At the end of its lifetime, all factories are cleanly destroyed. I like this form of encapsulation, as there is no confusion over who governs the lifetime of the factories.