I want to create a manager class which shall manage all the created objects of one type. Naturally this class should also create these objects. Therefore the client isn't allowed to create objects by himself, but instead must always use the manager class to do it.
Additionally the client is allowed to define his own classes which will be managed by one Manager.
template<class Type>
class Manager{
//...
Type* createInstance(){
Type* ptr = new Type();
//do sommething
return ptr;
}
};
The problem is: How do I restrict the creation of instances only to the manager class?
One possibility would be to declare the constructor as private and the Manager class as a friend class:
class A{
friend class Manager<A>;
private:
A(){}
~A(){}
};
Since the client is allowed to define own classes he could just declare the constructor public and the manager would still work without any problems. But the client would be able to create instances of those classes without the manager class witnessing it, resulting in bad behaviour/ressource management of the framework.
Is there a way to overcome this problem?
Managers of this sort are usually a bad pattern. The following code sample shows why.
It's the same problem as the one that says all destructors should be virtual. I use Manager to create a B, which derives from A, assign the object into an A* pointer. If it's destroyed as such, it goes through Manager::destroy(), which will probably not end well since it was created via Manager::make()
#include <iostream>
using namespace std;
template<class Type>
class Manager
{
public:
Manager(char *type)
{
mytype = type;
}
Type *make()
{
Type *ptr = new Type();
cout << "in Manager<" << mytype << ">::make() ptr->mytype is " << ptr->mytype << endl;
return ptr;
}
void destroy(Type *ptr)
{
cout << "in Manager<" << mytype << ">::destroy() ptr->mytype is " << ptr->mytype << endl;
delete ptr;
}
private:
char *mytype;
};
class A
{
friend class Manager<A>;
protected:
A()
{
mytype = "A";
cout << "in A()" << endl;
}
virtual ~A()
{
cout << "in ~A() mytype is " << mytype << endl;
}
char *mytype;
};
class B : public A
{
friend class Manager<B>;
protected:
B()
{
mytype = "B";
cout << "in B()" << endl;
}
virtual ~B()
{
cout << "in ~B() mytype is " << mytype << endl;
}
};
int main()
{
Manager<A> ma("A");
Manager<B> mb("B");
B *b = mb.make();
A *a = b;
ma.destroy(a); // This line calls Manager<A>::destroy. It should call Manager<B>::destroy.
return 0;
}
which produces the following as output:
in A()
in B()
in Manager<B>::make() ptr->mytype is B
in Manager<A>::destroy() ptr->mytype is B -- Oops - wrong destroy.
in ~B() mytype is B
in ~A() mytype is B
Which in turn means you can't use inheritance to it's full capability, which really defeats the purpose of using an OO language in the first place.
Depending on why you think you need a manager, there is probably a better solution.
If it's for memory management (unlikely given your original code snippet), overriding new and delete is worth taking a look at.
If it's for keeping track of all instances for processing purposes (e.g. objects in a game that get updated every game tick) then while it's a bit of a mental gearshift, a better solution is to integrate the manager into the class itself, as a set of static member functions and variables. Managers of this sort are almost invariably singletons, so making them static members / functions gets you to the same place semantically.
So you might have:
static set<A *> s_collection;
static void Heartbeat() // in class A
{
// lock s_collection here
for (auto it = s_collection.begin, end = s_collection.end() it != end; ++it)
{
// process *it
}
// unlock s_collection here
}
and then during A::A() you insert this into s_collection, and likewise during A::~A() you erase this.
Just be careful to use suitable synchronization primitives if you're multithreaded since most stl containers are not inherently thread safe.
You could use some variation of the passkey pattern to achieve this:
http://coliru.stacked-crooked.com/a/257860767a74a15e
Related
I have a hierarchy of classes:
class Base
{
public:
Base():a{5}{}
virtual ~Base(){};
int a;
};
class Derived : public Base
{
public:
Derived():b{10}{}
int b;
};
I then have a class template that operates on whatever type it is instanciated with:
template<typename T>
class DoStuff
{
public:
DoStuff():val{}{}
virtual ~DoStuff(){};
virtual void printDoStuff() = 0;
T getVal(){return val;};
private:
T val;
};
class DoStuffWithInt : public DoStuff<int>
{
public:
virtual void printDoStuff() override {cout << "val = " << getVal() << endl;}
};
class DoStuffWithBase : public DoStuff<Base>
{
public:
virtual void printDoStuff() {cout << "a = " << getVal().a << endl;}
};
Now I would like to have a hierarchy of class like this:
class DoStuffWithBase : public DoStuff<Base>
{
public:
virtual void printDoStuff() {printVal(); cout << "a = " << getVal().a << endl;}
};
// Wrong and will not compile, trying to make a point
class DoStuffWithDerived : public DoStuffWithBase<Derived>
{
public:
void printDoStuff() override {DoStuffWithBase::printDoStuff(); cout << "b = " << getVal().b << endl;}
};
Basically I would like to have DoStuffWithBase that operates on a base be extended so that I can reuse its functions, but the extended class DoStuffWithDerived should operate on a Derived type.
I managed to get something working by templating DoStuffWithBase with a pointer to Base and extending it:
template <class T>
static void deleteIfPointer(const T& t)
{
std::cout << "not pointer" << std::endl;
}
template <class T>
static void deleteIfPointer(T* t)
// ^
{
std::cout << "is pointer" << std::endl;
delete t;
}
template<typename T>
class DoStuff
{
public:
DoStuff():val{}{}
DoStuff(const T& value):val{value}{};
virtual ~DoStuff(){deleteIfPointer(val);}
virtual void printDoStuff() = 0;
T getVal(){return val;};
private:
T val;
};
class DoStuffWithBase : public DoStuff<Base*>
{
public:
// New base
DoStuffWithBase(): DoStuff(new Base()){}
DoStuffWithBase(Base* b) : DoStuff(b){}
virtual void printDoStuff() {printVal(); cout << "a = " << getVal()->a << endl;}
};
class DoStuffWithDerived : public DoStuffWithBase
{
public:
// New derived
DoStuffWithDerived(): DoStuffWithBase(new Derived()){}
void printDoStuff() override {DoStuffWithBase::printDoStuff(); cout << "b = " << static_cast<Derived*>(getVal())->b << endl;}
};
It works but there are several things I don't like:
The code is a lot more complicated, when 99% of the time, I won't need to extend a DoStuffWithX class, I will just use DoStuffWithInt, DoStuffWithClass, DoStuffWithAnotherClass etc... Here I had to add several constructors, a special case destructor and so on.
I have to use pointers and manage them (static_cast when needed, deletion...), all in order to avoid slicing and get the right type. Also, DoStuff::val should theorically not be null, but with a pointer there is no way I can prevent that (or atleast I don't know one). Maybe using smart pointers would help a bit here ? I am not super familiar with them.
I have to manage cases where T is a pointer and when it is not. For example, the deleteIfPointer function above, but also switching between . and -> and probably more.
Is there any simpler way to achieve what I am trying to do ? A design pattern or something else ? Am I stuck with my solution and is it somewhat good ?
Edit: I tried to implement it with std::variant as in #Tiger4Hire's answer:
class Derived : public Base
{
public:
Derived():b{10}{}
int b;
};
class Derived2 : public Base
{
public:
Derived2():c{12}{}
int c;
};
using DerivedTypes = std::variant<Derived, Derived2>;
struct VariantVisitor
{
void operator()(Derived& d)
{
d.b = 17;
}
void operator()(Derived2& d)
{
d.c = 17;
}
};
class DoStuffWithVariant : public DoStuff<DerivedTypes>
{
public:
void handleBasePart(Base& base)
{
cout << "a = " << base.a << endl;
base.a = 10;
}
virtual void printDoStuff() override
{
auto unionVal_l = getVal();
if (std::holds_alternative<Derived>(unionVal_l))
{
std::cout << "the variant holds a Derived!\n";
auto& derived_l = std::get<0>(unionVal_l);
cout << "b = " << derived_l.b << endl;
handleBasePart(derived_l);
}
else if (std::holds_alternative<Derived2>(unionVal_l))
{
std::cout << "the variant holds a Derived2!\n";
auto& derived2_l = std::get<1>(unionVal_l);
cout << "c = " << derived2_l.c << endl;
handleBasePart(derived2_l);
}
std::visit(VariantVisitor{}, unionVal_l);
}
};
What I like about it:
I don't have to use pointers.
I feel the code is less tricky, easier to understand.
What I don't like about it:
The code is all in one place and it deals with all the possible Derived types (and even the Base type) at once whereas with inheritance, classes are more specialized, you can really look at a class and directly know what it does, what it overrides etc... On the other hand one could argue that it means the algorithm is in one place instead of dispatched all over the classes hierarchy.
You can't have an abstract base class as your interface.
All in all it is a really good alternative, but I am still wondering if there is a simpler way to implement dynamic polymorphism ? Do you necessarily have to resort to (base class) pointers with dynamic polymorphism ? Are std::variant the way to go now ?
Edit2: 2 other drawbacks with variants that I didn't notice at first:
All your derived class and your base class have to be defined in the same library. Clients can't easily add a new Derived class since it would mean modifying the variant and they might not have access to it.
On the project I am working on, base classes are defined in one library, and are derived in other independant "sub" libraries. So if I try to use variant in my main library, it won't be able to access the Derived types in the sub libraries, which is a major issue.
If your base class implenting the variant (DoStuff here) has other members, when you call std::visit on the variant, you might have to also embark the needed other members of DoStuff. I think you should be able to use lambdas to capture them, but still, it's a lot less straightforward than using them directly as in the case of inheritance.
Your core problem is that you cast away your type information.
C++ will always call the right function, if it knows the correct type. This is why the pattern of pointer-to-base is almost always an anti-pattern (even though it is often taught as the "C++" way to do things).
Modern C++-style is to hold things as strongly-typed pointers, and cast them to the base pointer object, only when calling a function that takes a base-pointer as a parameter.
The standard supports this way of working by providing std::variant. Thus rather than
std::vector<Base*> my_list_of_things;
my_list_of_things.push_back(new Derived); // casting away type is bad
You start with
using DerivedTypes = std::variant<std::unique_ptr<Derived1>,
std::unique_ptr<Derived2>/*,etc*/>;
std::vector<DerivedTypes> my_list_of_things;
Now you can iterate over the list, calling a function which takes a pointer-to-base, casting away the type information only during the call.
You can also visit the members of the list, with a function (often a lambda) that knows exactly the type it is working on.
So you get the best of both worlds!
This does assume you have access to C++17 or above though, also that you are not working with code that is a library (compiled) but allows the library user to make their own classes. For example, libraries like Qt can't use this way of working.
If you don't have access to C++17, you may find curiously recursing templates fit much of what you are doing. (This is a controversial pattern though, as it is ugly and confusing)
So basically I have a class SomethingSwimming and a derived class Ship. I want to implement that upon some event a Ship may lose its special qualities (such as holding lobsters hostage) and become just another SomethingSwimming object.
To illustrate:
class SomethingSwimming
{
protected:
int m_treasures;
public:
SomethingSwimming(int treasures): m_treasures(treasures) {;}
virtual int howManyLobstersOnBoard() {return 0; }
};
class Ship: public SomethingSwimming
{
protected:
int m_lobstersOnBoard;
public:
Ship(int treasures, int lobstersOnBoard): SomethingSwimming(treasures), m_lobstersOnBoard(lobstersOnBoard) {;}
int howManyLobstersOnBoard() {return m_lobstersOnBoard; }
};
void crash(shared_ptr<SomethingSwimming>& b)
{
b = make_shared<SomethingSwimming>(100);
}
int main()
{
shared_ptr<SomethingSwimming> a = make_shared<Ship>(100, 12);
cout << "How many lobsters on board: " << a->howManyLobstersOnBoard() << endl;
crash(a);
cout << "How many lobsters on board: " << a->howManyLobstersOnBoard() << endl;
return 0;
}
My question is how to crash the Ship so it becomes only SomethingSwimming (so it's not a Ship anymore) without reinitializing.
There is no way of cutting away rest of the object while keeping the identity of the base sub object. You can make a new copy of the base sub object, and throw away the derived object.
Currently you create an unrelated object in crash and thereby m_treasures won't be affected by m_treasures of the previously pointed object. To create a copy of the original base sub object, you can do:
b = make_shared<SomethingSwimming>(*b);
Alternatively, at the call site you can treat an indirectly referred base as if it were not part of a derived object by calling virtual member functions statically:
a->SomethingSwimming::howManyLobstersOnBoard()
This will result in the value of m_treasures regardless of the most derived type of the object.
I'm asking this because even tho it seems to work, I feel like it shouldn't. The goal is to have a collection of objects kept alive, and general access to them. This is what I have at the moment:
Take a base pointer access:
struct base { virtual void tick() = 0; }; //ptr access
With different types that inherit from it:
struct :public base
{
void tick() { cout << "im type 1" << endl; }
}type1;
struct :public base
{
void tick() { cout << "im type 2" << endl; }
}type2;
Then a container class that should be able to store any amount of these serialized:
class control
{
struct xtype //struct for organizing objects
{
vector<char>charbuf; //serialized object
}xtype_template;
vector<xtype>xtype_vec;
public:
template<typename T> base* tell_to(T &input) //take object, return (base*)
{
xtype_template.charbuf.resize(sizeof(input));
memcpy(xtype_template.charbuf.data(), (char*)&input, sizeof(input));
xtype_vec.push_back(xtype_template); //push back with template after filling
return (base*)xtype_vec[xtype_vec.size() - 1].charbuf.data(); //pointer to data
}
}xcontainer; //container object
Then call:
auto ptr = controller.tell_to(type1); //becomes base*
auto ptr2 = controller.tell_to(type2);
And you can access either static-sized serialized object, as well as its states, by doing:
ptr->tick(); //which will output "im type 1" to console
ptr2->tick() //"im type 2"
But is this legal? Do these serialized versions have an actual type? Is accessing a serialized object directly with a base pointer illegal or wrong?
Closest probable answer: as the return on is_trivially_copyable show false, objects might not be safe to manage after getting base inheritance.
Follow up: This approach seems to work, and fiddling with is_trivially_copyable, seems to suggest that making an object inherit methods from, makes it unsafe. Basic methods do not make it unsafe however, and that makes me wonder if the safety only applies to exporting between systems, saving to file, or transferring over the network. Maybe the check just assumes the virtual reference makes them unsafe?
Follow up 2: If the characters remain in the same spot in memory, does it matter how they are accessed? Id wager that the only real problem with this approach, is if the objects stored were to have elements that would change their size after being stored.
What you are doing is illegal. You can only memcpy an object as an array of chars when the object is TriviallyCopyable. And your object is not, since it has virtual functions.
Instead of doing this, you should simply store a (unique) pointer to newly allocated object, and avoid any casts to enforce hierarchy. Like this:
class xtype
{
std::unique_ptr<base> ptr;
public:
template<typename T> base* serial_acc(T &input) //take object, return (base*)
{
static_assert(std::is_base_of<base, T>::value, "Please use proper type");
ptr = std::make_unique<base>(input);
return ptr;
}
} xcontainer;
Working example given by user Andy Prowl
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct base
{
virtual void tick() = 0;
};
struct type1 : base
{
virtual void tick() override { cout << "im type 1"<<endl; }
};
struct type2 : base
{
virtual void tick() override { cout << "im type 2" << endl; }
};
struct controller
{
vector<unique_ptr<base>> objects;
void cycle_tick(){ for (auto const& ptr : objects)ptr->tick();}
void add_object(unique_ptr<base> obj){ objects.emplace_back(move(obj));}
};
int main()
{
auto t1 = unique_ptr<type1>(new type1);
auto t2 = unique_ptr<type2>(new type2);
controller ctrl_object;
c.add_object(move(t1));
c.add_object(move(t2));
ctrl_object.cycle();
}
Members of a class are by default private in c++.
Hence, I wonder whether there is any possible use of creating a class that has all its members (variables and functions) set by default to private.
In other words, does there exist any meaningful class definition without any of the keywords public, protected or private?
There is a pattern, used for access protection, based on that kind of class: sometimes it's called passkey pattern (see also clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom) and How to name this key-oriented access-protection pattern?).
Only a friend of the key class has access to protectedMethod():
// All members set by default to private
class PassKey { friend class Foo; PassKey() {} };
class Bar
{
public:
void protectedMethod(PassKey);
};
class Foo
{
void do_stuff(Bar& b)
{
b.protectedMethod(PassKey()); // works, Foo is friend of PassKey
}
};
class Baz
{
void do_stuff(Bar& b)
{
b.protectedMethod(PassKey()); // error, PassKey() is private
}
};
Tag dispatching. It's used in the standard library for iterator category tags, in order to select algorithms which may be more efficient with certain iterator categories. For example, std::distance may be implemented something like this: (in fact it is implemented almost exactly like this in gnu libstdc++, but I've modified it slightly to improve readability)
template<typename Iterator>
typename iterator_traits<Iterator>::difference_type
distance(Iterator first, Iterator last)
{
return __distance(first, last,
typename iterator_traits<Iterator>::iterator_category());
}
Where __distance is a function which is overloaded to behave more efficiently for std::random_access_iterator_tag (which is an empty struct, but could just as easily be a class), simply using last - first instead of the default behavior of counting how many increments it takes to get first to last.
Application wide resource acquisition ?
#include <iostream>
class C {
C() {
std::cout << "Acquire resource" << std::endl;
}
~C() {
std::cout << "Release resource" << std::endl;
}
static C c;
};
C C::c;
int main() {
return 0;
}
As stated in comments below, I have I mind an industrial application that had to "lock" some hardware device while the program was running. But one might probably found other use for this as, after all, it is only some "degenerated" case or RAII.
As about using "private" methods outside the declaration block: I use a static member here. So, it is declared at a point where private members are accessible. You're not limited to constructor/destructor. You can even (ab)use a static methods and then invoke private instance methods using a fluent interface:
class C {
C() { std::cout << "Ctor " << this << std::endl; }
~C() { std::cout << "Dtor" << this << std::endl; }
static C* init(const char* mode) {
static C theC;
std::cout << "Init " << mode << std::endl;
return &theC;
}
C* doThis() {
std::cout << "doThis " << std::endl;
return this;
}
C* doThat() {
std::cout << "doThat " << std::endl;
return this;
}
static C *c;
};
C *C::c = C::init("XYZ")
->doThis()
->doThat();
int main() {
std::cout << "Running " << std::endl;
return 0;
}
That code is still valid (as all C members are accessible at the point of declaration of C::c). And will produce something like that:
Ctor 0x601430
Init XYZ
doThis
doThat
Running
Dtor0x601430
Meaningful? Good practice? Probably not, but here goes:
class DataContainer {
friend class DataUser;
int someDataYouShouldNotWorryAbout;
};
class DataUser {
public:
DataUser() {
container.someDataYouShouldNotWorryAbout = 42;
}
private:
DataContainer container;
};
No, there is no sense in creating a class without public member variable and/or functions, since there wouldn't be a way to access anything in the class. Even if not explicitly stated, the inheritance is private as well.
Sure, you could use friend as suggested, but it would create unneeded convolution.
On the other hand, if you use struct and not class to define a class, then you get everything public. That may make sense.
For example :
struct MyHwMap {
unsigned int field1 : 16;
unsigned int field2 : 8;
unsigned int fieldA : 24;
};
An admittedly ugly case from many, many years ago and not in C++ but the idea would still apply:
There was a bug in the runtime library. Actually fixing the offending code would cause other problems so I wrote a routine that found the offending piece of code and replaced it with a version that worked. The original incarnation had no interface at all beyond it's creation.
A derived class can be all-private, even its virtual methods redefining/implementing base-class methods.
To construct instances you can have friend classes or functions (e.g. factory), and/or register the class/instance in a registry.
An example of this might be classes representing "modules" in a library. E.g. wxWidgets has something like that (they are registered and do init/deinit).
So sometimes I want an object to have a reference to a shared resource (let's say something of type A), or alternatively to have its own copy of an A.
Furthermore the object may find itself inserted and manipulated inside of containers (vector, list, set).
So far what I know is that I will want to use an implementation of unique_ptr if I have a polymorphic type that is to be in a container. So for a class HasAnA which owns an A to be able to be placed inside a container while still allowing its A's to also be B's (B in this case being a derived class of A), it must be like this:
class A {
virtual void a() { std::cout << "A" << endl; }
payloadA payload;
};
class B: public A {
void a() { std::cout << "A(B)" << endl; }
void b() { std::cout << "B" << endl; }
payloadB payload;
};
class HasAnA {
std::unique_ptr<A> my_A; // this allows me to build a std::vector<HasAnA>
OtherStuff my_other_stuff;
};
So this is great, what I'm looking for is how to implement a class I'll call RefersAnA. I'd like for a RefersAnA to either have ownership of its own A, OR refer to an A owned by something else.
Let's see.
class RefersAnA {
std::unique_ptr<A> my_A; // represents my own A: when I die, this A is dealloc'd
A* not_my_A; // someone else's A.
OtherStuff my_other_stuff;
RefersAnA () {
// in here is code that would skip initializing my_A if a valid A* was provided.
}
};
To me this isn't really as friendly as I would like. Could I make some sort of template class which abstracts the notion of "either being a unique ptr to the resource or a raw ptr to the resource"? It needs one bit to say which of the two it is, and one pointer.
Here's an idea:
struct RefersOrOwns
{
std::unique_ptr<T> own;
T & ref;
RefersOrOwns() : own(new T), ref(*own) { }
RefersOrOwns(T & t) : ref(t) { }
};
(Instead of own(new T) I would of course prefer own(make_unique<T>()), but that's a separate issue.)