I have the following class definitions:
class Policy {
public:
virtual DigraphNode getBestMove(DigraphNode &node) const = 0;
};
class NoPolicy : public Policy{
virtual DigraphNode getBestMove(DigraphNode &node) const
{return DigraphNode();}
};
class Agent {
public:
static NoPolicy noPolicy;
Agent() : policy(noPolicy) {}
void setPolicy(Policy &p) {policy = p;}
Policy &getPolicy() {return policy;}
private:
Policy &policy; // pointer so polymorphism should work
};
Agent::policy may store an object of any descendant class of Policy. To avoid using pointers, I made this member a reference. However, then I need to initialize it in the constructor, which forced me to define an artificial policy NoPolicy as you see in the code. This works, but seems to be a bit artificial.
To complete the picture, I ended up having the following usage in the client code:
Policy &policy = Agent::noPolicy;
switch(agentTypes[a]) {
case NON_COMPLIANT:
policy = HeuristicBasedPolicy<MultiHeuristic>(nearExitH);
break;
etc.
I would very much appreciate if someone can suggest a more elegant way. Thanks!
Remark: The comment in the code is out-dated. Agent::policy is a reference, of course, not a pointer.
----------------------- AN EDIT (based on the feedback) ----------------------------------
Based on the feedback that I got (thanks!), I have modified the code. The class definitions are:
class Policy {
public:
virtual DigraphNode getBestMove(DigraphNode &node) const = 0;
};
class Agent {
public:
Agent() {policy = nullptr;}
void setPolicy(Policy *p) {policy = p;}
Policy &getPolicy() {return *policy;}
private:
Policy *policy; // pointer so polimorphism should work
};
The usage is:
vector<Policy *> agentPolicies; // need this only to free memory!
while (node->getDepth()) {
int a = node->getDepth() - 1;
Policy *myPolicy;
switch(agentTypes[a]) {
case NON_COMPLIANT:
myPolicy = new HeuristicBasedPolicy<MultiHeuristic>(nearExitH);
break;
...
}
agents[a].setPolicy(myPolicy);
agentPolicies.push_back(myPolicy);
}
...
for (int i = 0; i < agentPolicies.size(); i++)
delete(agentPolicies[i]);
Please let me know if this was the intention of the people who commented and replied.
Also, the array in the first line of the client code is needed only to keep pointers to later release them. Is this a normal state of affairs to have an array just for the bookkeeping of memory management? Thanks!
As you've seen, the reference has the problem that it must be
set in the constructor. And then can never be changed. If this
is what you want, and the class shouldn't be assignable
(probably the case in something called Agent), then
a reference is a valid solution. If the class needs to be
assignable, or you might need to change the policy after it is
constructed, then a pointer is the usual solution.
More generally, I've seen coding guidelines which forbid
reference members, because they make it impossible to make the
object assignable. Personally, I don't agree with them, because
a lot of classes have identity, and shouldn't support copy and
assignment. But it's probably fairly idiomatic to
systematically use pointers as class members, even when
a reference would work.
Having said that: using a no-op class is also fairly idiomatic
in cases like this. It's often easier to have a class invariant
policy != nullptr, and just do policy->something(), rather
than having to check for nullptr all over the place. (You may
still want the pointer, however, because you may want to change
the policy, particularly if it is a NullPolicy, after the
object has been constructed.) If you do this, you can (and
probably should) have functions like getPolicy return
a reference, and functions like setPolicy take a reference.
Also, classes like Policy are probably immutable (especially
if you share instances of them), so you should be using pointers
to const and references to const.
And finally: why do you want to avoid using pointers? Well
written C++, at least object oriented C++, will be full of
pointers.
Related
I'm curious if that's proper way of assignement
class Foo {
int x_;
public:
int & x() {
return x_;
}
};
My teacher is making assignement like that: obj.x() = 5;
But IMO that's not the proper way of doing it, its not obvious and it would be better to use setter here. Is that violation of clear and clean code ? If we take rule that we should read the code like a book that code is bad, am I right ? Can anyone tell me if am I right ? :)
IMO, this code is not a good practice in terms of evolution. If you need to provide some changes checking, formatting, you have to refactor your class API which can become a problem with time.
Having set_x() would be a way cleaner. Moreover, it will allow you to have checking mechanics in your setter.
a proper getter get_x() or x() could also apply some logic (format, anything...) before returning. In your case, you should return int instead of int& since setter should be used for modification (no direct modification allowed).
And truly speaking, this code doesn't really make sense... it returns a reference on a property making it fully modifiable. Why not having directly a public property then ? And avoid creating an additional method ?
Do you want control or not on your data? If you think so, then you probably want a proper getter and setter. If not, you probably don't need a method, just make it public.
To conclude, I would say you are right, because the way you see it would make it better over the time, prone to non-breaking change, better to read.
As the UNIX philosophy mentions : "Rule of Clarity: Clarity is better than cleverness."
Assuming that x() happens to be public (or protected) member the function effectively exposes an implementation: the is an int held somewhere. Whether that is good or bad depends on context and as it stands there is very little context.
For example, if x() were actually spelled operator[](Key key) and part of a container class with subscript operator like std::vector<T> (in which case Key would really be std::size_t) or std::map<Key, Value> the use of returning a [non-const] reference is quite reasonable.
On the other hand, if the advice is to have such functions for essentially all members in a class, it is a rather bad idea as this access essentially allows uncontrolled access to the class's state. Having access functions for all members is generally and indication that there is no abstraction, too: having setters/getters for members tends to be an indication that the class is actually just an aggregate of values and a struct with all public members would likely serve the purpose as well, if not better. Actual abstractions where access to the data matters tend to expose an interface which is independent of its actual representation.
In this example, the effect of returning a (non-const) reference is the same as if you made the variable public. Any encapsulation is broken. However, that is not a bad thing by default. A case where this can help a lot is when the variable is part of a complicated structure and you want to provide an easy interface to that variable. For example
class Foo {
std::vector<std::list<std::pair<int,int>>> values;
public:
int& getFirstAt(int i){
return values[i].[0].first;
}
};
Now you have an easy access to the first element of the first element at position i and dont need to write the full expression every time.
Or your class might use some container internally, but what container it is should be a private detail, then instead of exposing the full container, you could expose references to the elements:
class Bar {
std::vector<int> values; // vector is private!!
public:
int& at(int i){ // accessing elements is public
return values.at(i);
}
};
In general such a code confuses readers.
obj.x() = 5;
However it is not rare to meet for example the following code
std::vector<int> v = { 1, 0 };
v.back() = 2;
It is a drawback of the C++ language.
In C# this drawback was avoided by introducing properties.
As for this particular example it would be better to use a getter and a setter.
For example
class Foo {
int x_;
public:
int get_value() const { return x_; }
void set_value( int value ) { x_ = value; }
};
In this case the interface can be kept while the realization can be changed.
Given a typical strategy pattern
class Strategy
{
public:
virtual int execute() const = 0;
}
class StrategyA : public Strategy
{
public:
int execute() const override;
}
class StrategyB : public Strategy
{
public:
int execute() const override;
}
I believe the 'pre-C++11' way to implement a context class would be something like
class ContextRaw
{
public:
ContextRaw(Strategy* the_strategy);
~ContextRaw(); // Should this delete the_strategy_?
int execute() const;
private:
Strategy* the_strategy_;
}
To me, in this design it's not clear if Context should take responsibility for Strategy, and unless there is clear documentation stating otherwise, bad things might happen if it does
void trouble()
{
StrategyA a_concrete_strategy;
ContextRaw a_context(&a_concrete_strategy); // Oops, Context may try to delete stack variable
}
void more_trouble()
{
Strategy* a_concrete_strategy = new StrategyA;
ContextRaw* a_context = new ContextRaw(a_concrete_strategy);
ContextRaw* another_context = new ContextRaw(a_concrete_strategy);
delete a_context;
std::cout << another_context.execute() << std::endl; // Oops, the_strategy is deleted
}
In light of safe-pointers, should it now be preferable to inject a safe pointer, and have Context take ownership of the Strategy?
class ContextUnique
{
public:
ContextUnique() = delete;
ContextUnique(std::unique_ptr<Strategy> the_strategy);
~ContextUnique();
int execute() const;
private:
std::unique_ptr<Strategy> the_strategy_;
}
or if Strategy can be shared amongst different Context?
class ContextShared
{
public:
ContextShared() = delete;
ContextShared(std::shared_ptr<Strategy> the_strategy);
~ContextShared();
int execute() const;
private:
std::shared_ptr<Strategy> the_strategy_;
}
This design of course introduces problems of it's own, in particular only dynamically allocated Strategy's can be injected into Context.
The design is up to the implementator.
Notice that in your examples you reference different ways of screwing up with Strategy pattern using non C++11 pointers.
To answer directly to your question :
Yes you should use smart pointers in strategy pattern.
To further answer the question :
You should use smart pointers whenever possible.
The reason is that smart pointers practically are self documenting in terms of memory ownership policy, so you get rid of some the drawbacks of "If no good documentation".
Considering the prototype that you expose for your Context class , you can tell users what are your expectations :
unique_ptr if you expect the user to pass memory ownership to you
shared_ptr if you expect the same strategy implementation to be used on multiple owners
weak_ptr if you want the user to handle memory management
What is safer, it's up to you. However , you are able to tell users that the Context can share it's concrete strategy with other Contexts OR that there is 1 Concrete strategy per Context.
As a design approach, I would suggest to go with 1 Strategy / Context (so unique_ptr) since your concrete strategies might end up having some internal variables that are unique / context , and things will get complicated from there on.
You're doing it wrong.
In the light of std::function, everything you've just written is completely obsolete and you should just use std::function<int()> and some lambdas.
It strongly depends on what's the real purpose of Strategy objects whether they should be shared between various Context objects or owned by them.
At least when you use the shared or unique ptr, you clearly define your intentions. You should use a "raw" pointer only if you are going to "view" some other objects (you don't share nor own it - and you are sure that the pointing object won't outlive the pointed one).
Effective C++ by Scott Meyers tells in Chapter 5, Item 28 to avoid returning "handles" (pointers, references or iterators) to object internals and it definitely makes a good point.
I.e. don't do this:
class Family
{
public:
Mother& GetMother() const;
}
because it destroys encapsulation and allows to alter private object members.
Don't even do this:
class Family
{
public:
const Mother& GetMother() const;
}
because it can lead to "dangling handles", meaning that you keep a reference to a member of an object that is already destroyed.
Now, my question is, are there any good alternatives? Imagine Mother is heavy! If I now return a copy of Mother instead of a reference, GetMother is becoming a rather costly operation.
How do you handle such cases?
First, let me re-iterate: the biggest issue is not one of lifetime, but one of encapsulation.
Encapsulation does not only mean that nobody can modify an internal without you being aware of it, encapsulation means that nobody knows how things are implemented within your class, so that you can change the class internals at will as long as you keep the interface identical.
Now, whether the reference you return is const or not does not matter: you accidentally expose the fact that you have a Mother object inside of your Family class, and now you just cannot get rid of it (even if you have a better representation) because all your clients might depend on it and would have to change their code...
The simplest solution is to return by value:
class Family {
public:
Mother mother() { return _mother; }
void mother(Mother m) { _mother = m; }
private:
Mother _mother;
};
Because in the next iteration I can remove _mother without breaking the interface:
class Family {
public:
Mother mother() { return Mother(_motherName, _motherBirthDate); }
void mother(Mother m) {
_motherName = m.name();
_motherBirthDate = m.birthDate();
}
private:
Name _motherName;
BirthDate _motherBirthDate;
};
See how I managed to completely remodel the internals without changing the interface one iota ? Easy Peasy.
Note: obviously this transformation is for effect only...
Obviously, this encapsulation comes at the cost of some performance, there is a tension here, it's your judgement call whether encapsulation or performance should be preferred each time you write a getter.
Possible solutions depend on actual design of your classes and what do you consider "object internals".
Mother is just implementation detail of Family and could be completely hidden from Family user
Family is considered as composition of other public objects
In first case you shall completely encapsulate subobject and provide access to it only via Family function members (possibly duplicating Mother public interface):
class Family
{
std::string GetMotherName() const { return mommy.GetName(); }
unsigned GetMotherAge() const { return mommy.GetAge(); }
...
private:
Mother mommy;
...
};
Well, it can be boring if Mother interface is quite large, but possibly this is design problem (good interfaces shall have 3-5-7 members) and this will make you revisit and redesign it in some better way.
In second case you still need to return entire object. There are two problems:
Encapsulation breakdown (end-user code will depend on Mother definition)
Ownership problem (dangling pointers/references)
To adress problem 1 use interface instead of specific class, to adress problem 2 use shared or weak ownership:
class IMother
{
virtual std::string GetName() const = 0;
...
};
class Mother: public IMother
{
// Implementation of IMother and other stuff
...
};
class Family
{
std::shared_ptr<IMother> GetMother() const { return mommy; }
std::weak_ptr<IMother> GetMotherWeakPtr() const { return mommy; }
...
private:
std::shared_ptr<Mother> mommy;
...
};
If a read-only view is what you're after, and for some reason you need to avoid dangling handles, then you can consider returning a shared_ptr<const Mother>.
That way, the Mother object can out-live the Family object. Which must also store it by shared_ptr, of course.
Part of the consideration is whether you're going to create reference loops by using too many shared_ptrs. If you are, then you can consider weak_ptr and you can also consider just accepting the possibility of dangling handles but writing the client code to avoid it. For example, nobody worries too much about the fact that std::vector::at returns a reference that becomes stale when the vector is destroyed. But then, containers are the extreme example of a class that intentionally exposes the objects it "owns".
This goes back to a fundamental OO principle:
Tell objects what to do rather than doing it for them.
You need Mother to do something useful? Ask the Family object to do it for you. Hand it any external dependencies wrapped up in a nice interface (Class in c++) through the parameters of the method on the Family object.
because it can lead to "dangling handles", meaning that you keep a
reference to a member of an object that is already destroyed.
Your user could also de-reference null or something equally stupid, but they're not going to, and nor are they going to do this as long as the lifetime is clear and well-defined. There's nothing wrong with this.
It's just a matter of semantics. In your case, Mother is not Family internals, not its implementation details. Mother class instance can be referenced in a Family, as well as in many other entities. Moreover, Mother instance lifetime may even not correlate with Family lifetime.
So better design would be to store in Family a shared_ptr<Mother>, and expose it in Family interface without worries.
First off, sorry for the title. I couldn't really condense what I'm trying to ask into one phrase :(
I was reading this post, and it somehow got me thinking on function pointers. Specifically, I was wondering why it's "bad" (or, at least, rarely seen) to pass class member functions as function parameters, and then use that pointer on an existing object within that function.
Let's assume I have a template class "Container", which stores a single variable of type T and provides a method to get a const reference to this variable.
template<class T>
class Container {
public:
Container(T anObject) {
m_data = anObject;
}
const T& getData() const {
return m_data;
}
private:
T m_data;
};
Now, I would like to be able to execute member functions of T on m_data, but I don't want to make getData() non-const because that would enable all kinds of other mischief with the returned reference. My solution is to add a new public function, modifyData(...), to Container, which takes a function pointer to a member function of T as a parameter and executes it on m_data; like so:
// ...
void modifyData( void(typename T::*funcptr)(void) ) {
(m_data.*fptr)();
}
// ...
As-is, this will crash and burn if T is a pointer. For testing, I just created a specialized template for Container<T*> to address this, but I'm sure there would be a more elegant way.
A very construed example shows that this seems to work as intended:
// example class to be used with Container
class Data {
public:
Data() {m_count = 0; }
void incrementCount() { m_count++; }
int getCount() const { return m_count; }
private:
int m_count;
};
// ... in main.cpp:
Data dat;
Container<Data*> DCont(dat);
std::cout << cl.getData()->getCount() << std::endl; // outputs 0
DCont.modifyData<Data>(&Data::incrementCount);
std::cout << cl.getData()->getCount() << std::endl; // outputs 1
// compiler catches this:
// DCont.modifyData<SomeOtherClass>(&Data::incrementCount);
// this probably does something bad:
// DCont.modifyData<SomeOtherClass>(&SomeOtherClass::someFunc);
Now, instinctively this just seems like a horribly twisted way of doing things, and I've never seen code that works like this. But my question is, is there a performance/security reason why something like this is bad, or is it something that's just considered bad practice? If it's "just" bad practice, then why is that?
Obvious limitations that I could think of are that something like
// DCont.modifyData(&SomeOtherClass::someFunc);
will probably crash at runtime, but I think that could be addressed by checking the type of U against T in incrementData(). Also, as it is, modifyData only accepts void (*)() functions, but this could probably be addressed with variadic templates.
This example is obviously very construed and not implemented so well, but I think (hope?) it's good enough to explain what I'm talking about.
Thanks!
EDIT: There seems to be some confusion as to what the question is. Basically, this is the scenario I'm talking about: You have a bunch of classes from some library that you're trying to store in the container, and another function that generates certain containers; Now, you want the user to be able to call existing member functions on the objects within these containers, but not to modify the actual objects (like when returning a non-const reference with the getter). An actual implementation would probably use some sort of variadic template to be useful, but I need to think that through some more before posting example code.
In short, I'd like to limit a user's access to container members to only member functions of that member. Is there an easier way of doing this, or does this way not work in the way I was intending?
I don't have any problem with your architecture - I don't see it as bad practice. To me it seems quite a laborious way to protect data and doesn't really help you much in that the user can use any void function to modify the contained data which isn;t really a contract on what can and can't be changed.
I think the reason this construct is so rarely seen is that your requirement and goals of the container class are unusual.
Suppose I have two instances of the same class. The class has a pointer to some data, and I want the instances to exchange the pointers as part of some private function's algorithm, but without compromising the data to everybody else by giving a direct access to it through a public function.
My first idea was to add a static variable of type bool called exchange, and two methods: a private one: void requestExchange() and a public one: Data** respond().
requestExchange would set exchange to true, and will be immediately followed with respond() from the instance of choice, which will do the following:
if(exchange==true){
exchange=false;
return data;
}
else{return...?!
This was when I realized that I have no way of simulating "NO OP" since data may in fact be NULL, so supposedly everything goes as a response. Any ideas as to what can be done?
UPDATE: I thought a bit about it, and since the request-respond combo will only be called in the context where NULL as a result will be meaningful (exchange is most certainly true) I suppose I can simply return NULL and simulate a NO OP this way. To an outsider NULL as a result will be useless... But I'm still interested in suggestions. There must be a more well structured way of doing this.
Objects of the same class can access each others' private data directly. You often see this in copy constructors, for example.
Your description of the problem is not very clear. Why can't you just make respond() a private function?
The idea with a static class member is fraught with peril. What if two pairs of such instances want to communicate simultaneously? What if one sets the exchange flag and then dies before it comes around to calling respond()? What about thread safety?
As for returning a NO-OP or error indicator, you can either use exceptions (that's what they are for, but if your project does not use exceptions it's not a good idea to introduce them suddenly), or go the route of boost::optional.
Might be best to separate your concerns with regards to returning the data and exchanging it.
class Foo
{
public:
Bar* data()
{
return pData;
}
private:
void exchangeData(Foo& Rhs)
{
if (this != &Rhs)
{
Bar* pTmp = pData;
pData = Rhs.pData;
Rhs.pData = pTmp;
}
}
Bar* pData;
}
Hopefully it's along the lines of what you want? The question isn't super clear....
I probably missed the point of your question. Why does this not do what you want?
class CMyClass
{
public:
void ExchangePointerWith( CMyClass& rhs );
private:
void* m_MyPtr;
};
and:
void CMyClass::ExchangePointerWith(CMyClass &rhs)
{
void* tmp= m_MyPtr;
m_MyPtr= rhs.m_MyPtr;
rhs.m_MyPtr= tmp;
}
Use std::swap() and build your class's own swap method then you know it should be exception safe. And swap() is a standard routing that most class should implement to make them efficient for the STL.
Remember that a class is automatically a friend of itself. So it can access the private member variables of another instance of the same class. See (Friend scope in C++)
#include <algorithm>
class myX
{
public:
void swap(myX& rhs) throw()
{
std::swap(data,rhs.data);
}
private:
void* data;
};