I Have two classes:
First:
class Thing {
public:
int code;
string name;
string description;
int location;
bool canCarry;
Thing(int _code, string _name, string _desc, int _loc, bool _canCarry) {
code = _code;
name = _name;
description = _desc;
location = _loc;
canCarry = _canCarry;
}
};
Second:
class Door: public Thing {
private:
bool open;
public:
int targetLocation;
Door(int _code, string _name, string _desc, int _loc, int _targetLoc) :
Thing(_code, _name, _desc, _loc, false) {
open = false;
targetLocation = _targetLoc;
}
void Use() {
open = true;
}
void Close() {
open = false;
}
bool isOpen() {
return open;
}
};
Forget private/public atributes...
I need to store some objects of base class and some objects of derived class,
something like this:
vector < Thing*> allThings;
things.push_back(new Thing(THING1, "THING1", "some thing", LOC1, true));
things.push_back(new Door(DOOR1, "DOOR1", "some door", LOC1, LOC2));
But in this case, functions Use(), Open(), and isOpen() will not be reachable because of slicing..
Do you have some suggestions, how to store these objects together without creating new structure of vector<Thing*> and vector<Door*>??
Thanks
A good solution to a problem when you need a container of objects with polymorphic behavior is a vector of unique pointers:
std::vector<std::unique_ptr<Thing>>
There would be no slicing in this situation, but you would have to figure out when it's OK to call Use(), Open(), and isOpen().
If you can move the methods from the derived class into the base, go for it; if you cannot do that because it makes no sense for a Thing to have isOpen(), consider using a more advanced solution, such as the Visitor Pattern:
class Thing;
class Door;
struct Visitor {
virtual void visitThing(Thing &t) = 0;
virtual void visitDoor(Door &d) = 0;
};
class Thing {
...
virtual void accept(Visitor &v) {
v.visitThing(*this);
}
};
class Door : public Thing {
...
virtual void accept(Visitor &v) {
v.visitDoor(*this);
}
}
Store pointers instead of instances, and declare public and protected methods as virtual in the base class(es).
Related
Say I have this class called Dog. Every dog has a different name but the same barking voice (which is loaded from a resource file).
class Dog {
public:
Dog(const string &name) : _name(name) {
_barkingVoice.load();
}
~Dog() {
_barkingVoice.free();
}
string getName() const { return _name; }
void bark() { _barkingVoice.play(); }
private:
string _name;
VoiceResource _barkingVoice;
};
I want to call _barkingVoice.load() only if the instance of Dog is the first one, and _barkingVoice.free() only if there are no more instances of Dog.
The obvious solution is to set _barkingVoice as static and keep a reference counter of Dog as a data member.
My question is if there's an easier way to do this. Maybe an std implementation or something like that.
Make a reusable class to encapsulate the reference counting:
template<class ResourceType, class OwnerType>
class RefCounted {
public:
RefCounted() { if (++_refCount == 1) _resource.load(); }
virtual ~RefCounted() { if (--_refCount == 0) _resource.free(); }
ResourceType& operator*() { return _resource; }
ResourceType* operator->() { return &_resource; }
private:
static unsigned _refCount;
static ResourceType _resource;
};
template<class T, class U> unsigned RefCounted<T, U>::_refCount = 0;
template<class T, class U> T RefCounted<T, U>::_resource;
class Dog {
public:
Dog(const string &name) : _name(name) { }
string getName() const { return _name; }
void bark() { _barkingVoice->play(); }
private:
string _name;
RefCounted<VoiceResource, Dog> _barkingVoice;
};
Every template instantiation will have their own _refCount and _resource.
The second template parameter is to handle cases where you instantiate RefCounted with the same ResourceType but want to have separate reference counting for those instantiations. E.g. if you add a Cat class and want it to have its own Refcounted<VoiceResource>:
class Cat {
// ...
private:
RefCounted<VoiceResource, Cat> _meowingVoice;
};
First, why VoiceResource is not static? If it's shared between all instances of Dog, it should be. Else, you will need to load or copy the resuorce at every constructor call.
Have a static variable static int instanceCount;, that is set to 0. In every casual, copy and move (C++11) constructor increment it, in destructor decrement it. That will give you opportunity to do what you wanted.
That will basicly work like shared_ptr<T> does, the might be a way to use it here instead of writing your own code, I just can't figure that out.
class Dog {
public:
Dog(const string &name) : _name(name) {
loadResource();
}
Dog(const Dog& b) : name(b.name) {
loadResource();
}
// only C++11:
Dog(Dog&& b) : name(std::move(b.name)) {
loadResource();
}
~Dog() {
freeResource();
_barkingVoice.free();
}
string getName() const { return _name; }
void bark() { _barkingVoice.play(); }
private:
string _name;
static VoiceResource _barkingVoice;
static int instanceCount;
static void loadResource() {
if (instanceCount == 0) {
_barkingVoice.load();
}
++instanceCount;
}
static void freeResource() {
--instanceCount;
if (instanceCount == 0) {
_barkingVoice.free();
}
}
};
int Dog::instanceCount = 0;
Make _barkingVoice a std::shared_ptr<VoiceResource>.
A shared_ptr does exactly what you need: uses references counting to track the deletion of the last object, when it will deallocate the resource.
I am trying to define an interface called "Algorithm" which has a pure virtual method insertData(InputData* input).
The implementation of the interface is called "Algorithm1" and i want to implement method "insertData" using as a parameter "SpecificData" which is a child of "InputData" class.
Is it possible without type casting?
Obviously with this code i get an error from the compiler that the virtual function "insertData" is pure within "Algorithm1".
class Algorithm{
public:
virtual ~Algorithm();
virtual void insertData(InputData* input) = 0;
};
class Algorithm1 : public Algorithm{
public:
Algorithm1();
virtual ~Algorithm1();
void insertData(SpecificData* input){
input.getID();
input.getAdditionalNumbers;
/*Process input information etc.*/ };
};
class InputData{
public:
void setID(int id){ this->id = id; }
int getID(){ return id;};
private:
int id;
};
class SpecifiData : public InputData{
public:
list<int> getAdditionalNumbers(){/*Return various Numbers*/};
private:
list<int> extraInfo;
};
void main(){
SpecificData* data = new SpecificData();
Algorithm* alg = new Algorithm1();
alg->insertData(data);
}
For insertData to be the same function (rather than "hiding" the original insertData, you need the two functions to have the same arguments (and same return type).
The whole idea of interfaces using virtual functions is that "they appear the same from the outside". You should be able to build a list of objects, and perform the same operation with the same input data for all of the objects in the list.
If you are breaking that principle, you are "doing it wrong".
No, it wouldn't make sense.
Think about the following scenario - you have a container (vector/set w/e) of Algorithm* type objects and a function that takes this container and a InputData* in as an input and then iterate over them and call insertData(in) on each of the objects in the container, this of course should work properly, but if one of the objects in your container is of type Algorithm1 what will happen then?
I think, this is a typical example of "Factory Method" in design pattern term.
class Algorithm
{
public:
virtual ~Algorithm();
virtual void insertData(InputData* input) = 0;
};
class InputData
{
public:
void setID(int id){ this->id = id; }
int getID(){ return id;};
virtual list<int> getAdditionalNumbers() = 0;
private:
int id;
};
class Algorithm1 : public Algorithm
{
public:
Algorithm1();
virtual ~Algorithm1();
void insertData(InputData* input){
input.getID();
input.getAdditionalNumbers;
/*Process input information etc.*/ };
};
class SpecifiData : public InputData
{
public:
// implementation
virtual list<int> getAdditionalNumbers(){/*Return various Numbers*/};
private:
list<int> extraInfo;
};
void main()
{
InputData* data = new SpecificData();
Algorithm* alg = new Algorithm1();
alg->insertData(data);
}
I have an object presented as a reference/pointer to an interface. I would like to call a method on the concrete object if that method is present, without changing the interface, breaking encapsulation, or writing any horrible hacks. How can it be done?
Here's an example.
I have an interface:
class IChatty
{
public:
virtual ~IChatty() {};
virtual std::string Speak() const = 0;
};
And multiple concrete implementation of this interface:
class SimpleChatty : public IChatty
{
public:
~SimpleChatty() {};
virtual std::string Speak() const override
{
return "hello";
}
};
class SuperChatty : public IChatty
{
public:
void AddToDictionary(const std::string& word)
{
words_.insert(word);
}
virtual std::string Speak() const override
{
std::string ret;
for(auto w = words_.begin(); w != words_.end(); ++w )
{
ret += *w;
ret += " ";
}
return ret;
}
private:
std::set<std::string> words_;
};
The SuperChatty::AddToDictionary method is not present in the abstract IChatty interface, although it could be included in another, new interface.
In the real world, these objects are constructed through factories, themselves concrete instantiations of an abstract interface. However for our purposes that's orthogonal to the problem at hand:
int main()
{
IChatty* chatty = new SuperChatty;
chatty->AddToDictionary("foo");
std::cout << chatty->Speak() << std::endl;
}
Since AddToDictionary isn't part of the IChatty interface (and can't be part of it), I can's call it.
How can I call AddToDictionary on the chatty pointer without breaking encapsulation, writing some horrible hack, or taking any other design shortcuts?
NOTE: In the real world, the dictionary is part of the SuperChatty object itself, and cannot be separate from it.
NOTE2: I do not want to downcast to the concrete type.
Have dictionary be an object which can be updated and referenced by SuperChatty:
class Dictionary {
public:
void add(const std::string& word);
const std::set<std::string>>& words() const;
//..
};
class SuperChatty : public IChatty
{
public:
SuperChatty(Dictionary& dictionary) :
dictionary(dictionary) {
}
virtual std::string Speak() const override
{
auto words = dictionary.words();
ostringstream oss;
copy(words.begin(), words.end(),
ostream_iterator<string>(oss, " "));
return oss.str();
}
};
Usage:
int main()
{
Dictionary dictionary;
IChatty* chatty = new SuperChatty(dictionary);
dictionary.add("foo");
std::cout << chatty->Speak() << std::endl;
}
edit
Okay, the question changed.
If you're doing this properly, you need to isolate yourself from the bad underlying system:
struct Dictionary {
virtual ~Dictionary () {}
virtual void add(const std::string& word) = 0;
};
struct Instrumenter {
virtual ~Instrumenter () {}
virtual void addDictionary(Dictionary& dictionary) = 0;
};
struct Chatter {
virtual ~Chatter() {}
virtual string speak() const = 0;
virtual void instrument(Instrumenter& instrumenter) = 0;
};
These are implemented as:
class BasicChatter : public Chatter {
virtual string speak() const {
return chatty.Speak();
}
virtual void instrument(Instrumenter& instrumenter) {
// do nothing
}
private:
SimpleChatty chatty;
};
class SuperChatter : public Chatter {
SuperChatter () : dictionary(chatty);
virtual void instrument(Instrumenter& instrumenter) {
instrumenter.addDictionary(dictionary);
}
virtual string speak() const {
return chatty.Speak();
}
private:
SuperChatty chatty;
DictionaryImpl dictionary;
};
Make it derive from another interface and simply check, whether you can cast the object to that interface or not.
class IDictionary
{
public:
virtual ~IDictionary() {};
virtual void AddToDictionary(const std::string& word) = 0;
};
class SuperChatty : public IChatty, public IDictionary
{
... as before ...
};
int main()
{
IChatty* chatty = new SuperChatty;
IDictionary *dict = dynamic_cast<IDictionary*>(chatty);
if (dict) dict->AddToDictionary("foo");
std::cout << chatty->Speak() << std::endl;
}
The main problem is that you're trowing away information that you need.
So the main solution is to not throw away information, but there's not enough code presented to flesh out the details of that.
Secondly, a tehcnical kludge solution is to just downcast, using dynamic_cast:
IChatty* newThingy();
int main()
{
IChatty* chatty = newThingy();
if( SuperChatty* p_super_chatty = dynamic_cast<SuperChatty*>( chatty ) )
{
p_super_chatty->AddToDictionary("foo");
}
std::cout << chatty->Speak() << std::endl;
}
You can downcast safely because the know static type IChatty is polymorphic.
For this particular example, there's no reason to not create the object as this:
SuperChatty* chatty = new SuperChatty;
chatty->AddToDictionary("foo");
You can still pass chatty in the above segment as IChatty pointer or reference, e.g.
void Talk(IChatty *ch)
{
ch->Speak();
}
[Likewise for storing the chatty in a vector<IChatty*> or something like that].
My point here is that if you are going to use the "new" interface functions, then you probably also want to create the class that has the new interface.
Adding code to "try to cast it", etc, gets very messy very quickly, and is error prone.
I think I messed up somehow in my design because I want to keep a vector of various object types. These types all share a common base class. Example:
Class Buick: AmericanCar
{
}
Class Ford: AmericanCar
{
}
then I did:
vector<AmericanCar*> cars_i_own;
Now, I have my vector of pointers but I don't have the derived class which is what I need. I thought about adding a GetType/SetType function to the base class and then use a dynamic cast. This is clunky though. Did i use the wrong design for this?
Well, what are you trying to do with it? Get the name or cost? You would have something like:
class Car
{
public:
virtual ~Car(void) {}
virtual std::string location(void) const = 0;
virtual std::string name(void) const = 0;
virtual double cost(void) const = 0;
}
class AmericanCar
{
public:
virtual ~AmericanCar(void) {}
virtual std::string location(void) const
{
return "America";
}
}
class Buick : public AmericanCar
{
public:
virtual std::string name(void) const
{
return "Buick";
}
virtual double cost(void) const
{
return /* ... */;
}
}
class Ford : public AmericanCar
{
public:
virtual std::string name(void) const
{
return "Ford";
}
virtual double cost(void) const
{
return /* ... */;
}
}
Now you can call these methods polymorphically.
This is somewhat strange, though. You don't need a different class to store names and cost like this:
class Car
{
public:
Car(const std::string& pLocation,
const std::string& pName,
double pCost) :
mLocation(pLocation),
mName(pName),
mCost(pCost)
{
}
const std::string& location(void) const
{
return mLocation;
}
void location(const std::string& pLocation)
{
mLocation = pLocation;
}
const std::string& name(void) const
{
return mName;
}
void name(const std::string& pName)
{
mName = pName;
}
const double cost(void) const
{
return mCost;
}
void cost(double pCost)
{
mCost = pCost;
}
private:
std::string mLocation;
std::string mName;
double mCost;
}
// make cars
std::vector<Car> cars;
cars.push_back(Car("America", "Buick", /* ... */));
The purpose of inheritance / polymorphism is so you don't need to care which derived type you are dealing with.
In particular I think storing data, such as make of car, country of origin etc, encoded in a class hierarchy doesn't seem to be particularly beneficial. Does an AmericanCar do something fundamentally different from, say, a Japanese car (other than consuming more fuel, which again can be better stored in a data member)?
Why do you need to know the derived class? Normally you would have virtual functions to take care of any behavior differences between the two derived classes.
The goal is that the code using the parent class shouldn't have to know the exact class it's working with.
You can use typeid to determine the derived class:
struct Base
{
virtual ~Base() {}
};
struct Derived : public Base { };
int main()
{
Base* b = new Derived();
std::cout << typeid(*b).name() << std::endl;
}
This outputs: "Derived".
But, usually with polymorphism the point is that you shouldn't be concerned with this. You simply call a base-class member function and the proper derived-class member function is called at runtime.
Is there anyway to have a sort of virtual static member in C++?
For example:
class BaseClass {
public:
BaseClass(const string& name) : _name(name) {}
string GetName() const { return _name; }
virtual void UseClass() = 0;
private:
const string _name;
};
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass("DerivedClass") {}
virtual void UseClass() { /* do something */ }
};
I know this example is trivial, but if I have a vector of complex data that is going to be always the same for all derived class but is needed to be accessed from base class methods?
class BaseClass {
public:
BaseClass() {}
virtual string GetName() const = 0;
virtual void UseClass() = 0;
};
class DerivedClass : public BaseClass {
public:
DerivedClass() {}
virtual string GetName() const { return _name; }
virtual void UseClass() { /* do something */ }
private:
static const string _name;
};
string DerivedClass::_name = "DerivedClass";
This solution does not satify me because I need reimplement the member _name and its accessor GetName() in every class. In my case I have several members that follows _name behavior and tenths of derived classes.
Any idea?
Here is one solution:
struct BaseData
{
const string my_word;
const int my_number;
};
class Base
{
public:
Base(const BaseData* apBaseData)
{
mpBaseData = apBaseData;
}
const string getMyWord()
{
return mpBaseData->my_word;
}
int getMyNumber()
{
return mpBaseData->my_number;
}
private:
const BaseData* mpBaseData;
};
class Derived : public Base
{
public:
Derived() : Base(&sBaseData)
{
}
private:
static BaseData sBaseData;
}
BaseData Derived::BaseData = { "Foo", 42 };
It seems like the answer is in the question - the method you suggested seems to be the right direction to go, except that if you have a big number of those shared members you might want to gather them into a struct or class and past that as the argument to the constructor of the base class.
If you insist on having the "shared" members implemented as static members of the derived class, you might be able to auto-generate the code of the derived classes. XSLT is a great tool for auto-generating simple classes.
In general, the example doesn't show a need for "virtual static" members, because for purposes like these you don't actually need inheritance - instead you should use the base class and have it accept the appropriate values in the constructor - maybe creating a single instance of the arguments for each "sub-type" and passing a pointer to it to avoid duplication of the shared data. Another similar approach is to use templates and pass as the template argument a class that provides all the relevant values (this is commonly referred to as the "Policy" pattern).
To conclude - for the purpose of the original example, there is no need for such "virtual static" members. If you still think they are needed for the code you are writing, please try to elaborate and add more context.
Example of what I described above:
class BaseClass {
public:
BaseClass(const Descriptor& desc) : _desc(desc) {}
string GetName() const { return _desc.name; }
int GetId() const { return _desc.Id; }
X GetX() connst { return _desc.X; }
virtual void UseClass() = 0;
private:
const Descriptor _desc;
};
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass(Descriptor("abc", 1,...)) {}
virtual void UseClass() { /* do something */ }
};
class DerDerClass : public BaseClass {
public:
DerivedClass() : BaseClass("Wowzer", 843,...) {}
virtual void UseClass() { /* do something */ }
};
I'd like to elaborate on this solution, and maybe give a solution to the de-initialization problem:
With a small change, you can implement the design described above without necessarily create a new instance of the "descriptor" for each instance of a derived class.
You can create a singleton object, DescriptorMap, that will hold the single instance of each descriptor, and use it when constructing the derived objects like so:
enum InstanceType {
Yellow,
Big,
BananaHammoc
}
class DescriptorsMap{
public:
static Descriptor* GetDescriptor(InstanceType type) {
if ( _instance.Get() == null) {
_instance.reset(new DescriptorsMap());
}
return _instance.Get()-> _descriptors[type];
}
private:
DescriptorsMap() {
descriptors[Yellow] = new Descriptor("Yellow", 42, ...);
descriptors[Big] = new Descriptor("InJapan", 17, ...)
...
}
~DescriptorsMap() {
/*Delete all the descriptors from the map*/
}
static autoptr<DescriptorsMap> _instance;
map<InstanceType, Descriptor*> _descriptors;
}
Now we can do this:
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.BananaHammoc)) {}
virtual void UseClass() { /* do something */ }
};
class DerDerClass : public BaseClass {
public:
DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.Yellow)) {}
virtual void UseClass() { /* do something */ }
};
At the end of execution, when the C runtime performs uninitializations, it also calls the destructor of static objects, including our autoptr, which in deletes our instance of the DescriptorsMap.
So now we have a single instance of each descriptor that is also being deleted at the end of execution.
Note that if the only purpose of the derived class is to supply the relevant "descriptor" data (i.e. as opposed to implementing virtual functions) then you should make do with making the base class non-abstract, and just creating an instance with the appropriate descriptor each time.
I agree with Hershi's suggestion to use a template as the "base class". From what you're describing, it sounds more like a use for templates rather then subclassing.
You could create a template as follows ( have not tried to compile this ):
template <typename T>
class Object
{
public:
Object( const T& newObject ) : yourObject(newObject) {} ;
T GetObject() const { return yourObject } ;
void SetObject( const T& newObject ) { yourObject = newObject } ;
protected:
const T yourObject ;
} ;
class SomeClassOne
{
public:
SomeClassOne( const std::vector& someData )
{
yourData.SetObject( someData ) ;
}
private:
Object<std::vector<int>> yourData ;
} ;
This will let you use the template class methods to modify the data as needed from within your custom classes that use the data and share the various aspects of the template class.
If you're intent on using inheritance, then you might have to resort to the "joys" of using a void* pointer in your BaseClass and dealing with casting, etc.
However, based on your explanation, it seems like you need templates and not inheritance.
#Hershi: the problem with that approach is that each instance of each derived class has a copy of the data, which may be expensive in some way.
Perhaps you could try something like this (I'm spit-balling without a compiling example, but the idea should be clear).
#include <iostream>
#include <string>
using namespace std;
struct DerivedData
{
DerivedData(const string & word, const int number) :
my_word(word), my_number(number) {}
const string my_word;
const int my_number;
};
class Base {
public:
Base() : m_data(0) {}
string getWord() const { return m_data->my_word; }
int getNumber() const { return m_data->my_number; }
protected:
DerivedData * m_data;
};
class Derived : public Base {
public:
Derived() : Base() {
if(Derived::s_data == 0) {
Derived::s_data = new DerivedData("abc", 1);
}
m_data = s_data;
}
private:
static DerivedData * s_data;
};
DerivedData * Derived::s_data = 0;
int main()
{
Base * p_b = new Derived();
cout getWord() << endl;
}
Regarding the follow-up question on deleting the static object: the only solution that comes to mind is to use a smart pointer, something like the Boost shared pointer.
It sounds as if you're trying to avoid having to duplicate the code at the leaf classes, so why not just derive an intermediate base class from the base class. this intermediate class can hold the static data, and have all your leaf classes derive from the intermediate base class. This presupposes that one static piece of data held over all the derived classes is desired, which seems so from your example.