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;
};
Related
In my program I need a factory function that provides instances of separate class because I need control over the details of each instance and to be aware of how many instances are in existence at a time. In particular returning a std::shared_ptr is ideal, but this is initially impossible due to a known issue with the "make" fucntions of the std::pointer types as they would need to be friends with my Widget class as well, which isn't portable since it relies on the current implementation of those methods that may change.
To get around this, I want to employ the Passkey idiom, which was directly recommend for this situation as described at the bottom of this: https://abseil.io/tips/134. I also based my implementation off the lessons learned here: https://arne-mertz.de/2016/10/passkey-idiom/
This is a sample project that uses my same setup as my full project:
#include <iostream>
class Widget
{
public:
class Key
{
friend class Factory;
private:
Key() {};
Key(const Key&) = default;
};
int mTest;
explicit Widget(Key, int test) { mTest = test; }
int getTestVar() { return mTest; }
};
class Factory
{
public:
int mTestPass;
Factory(int input) { mTestPass = input; }
std::shared_ptr<Widget> factoryMake() { return std::make_shared<Widget>(Widget::Key{}, mTestPass); }
};
int main()
{
Factory testFactory(10);
std::shared_ptr<Widget> testWidget = testFactory.factoryMake();
std::cout << testWidget->getTestVar();
return 0;
}
However, I get
Error C2248 'Widget::Key::Key': cannot access private member declared in class 'Widget::Key' TestProject ...\include\xmemory 204
This has me completely lost, since the error coming from xmemory.cpp indicates that std::make_shared is sill trying to access a private constructor. As far as I'm aware, the construction of the Key instance occurs within the factoryMake() function, which belongs to Factory, and then that instance is passed into the std::make_shared function; therefore, std::make_shared should not need access to the Key constructor since an already constructed instance is being passed to it, which is the entire point of using this idiom in this context. The class itself is public so it should have no issues interacting with the type Key, only the constructor should be inaccessible.
In the end I can just skip using std::make_shared and instead use the shared_ptr(*T) constructor with a raw pointer, but this is slightly less efficient due to the extra allocation it requires, as noted in my first link. It isn't a big deal as I'm not making many widgets but I'd ultimately prefer to get the more ideal implementation working.
What am I missing here?
The problem is that the compiler needs to copy your Widget::Key when you call std::make_shared, and you have declared the copy constructor private. You can solve this in one of two ways:
Make the copy constructor of Widget::Key public.
Change the Widget constructor to take the Widget::Key by const reference:
explicit Widget(const Key&, ...
I have two classes that are used in a project. One class, Callback, is in charge of holding information from a callback. Another class, UserInfo, is the information that is exposed to the user. Basically, UserInfo was supposed to be a very thin wrapper that reads Callback data and gives it to the user, while also providing some extra stuff.
struct Callback {
int i;
float f;
};
struct UserInfo {
int i;
float f;
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
The problem is that adding members to Callback requires identical changes in UserInfo, as well as updating operator= and similarly dependent member functions. In order to keep them in sync automatically, I want to do this instead:
struct Callback {
int i;
float f;
};
struct UserInfo : Callback{
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
Now UserInfo is guaranteed to have all of the same data members as Callback. The kicker is, in fact, the data member thekicker. There are no virtual destructors declared in Callback, and I believe the other coders want it to stay that way (they feel strongly against the performance penalty for virtual destructors). However, thekicker will be leaked if a UserInfo type is destroyed through a Callback*. It should be noted that it is not intended for UserInfo to ever be used through a Callback* interface, hence why these classes were separate in the first place. On the other hand, having to alter three or more pieces of code in identical ways just to modify one structure feels inelegant and error-prone.
Question: Is there any way to allow UserInfo to inherit Callback publicly (users have to be able to access all of the same information) but disallow assigning a Callback reference to a UserInfo specifically because of the lack of virtual destructor? I suspect this is not possible since it is a fundamental purpose for inheritance in the first place. My second question, is there a way to keep these two classes in sync with each other via some other method? I wanted to make Callback a member of UserInfo instead of a parent class, but I want data members to be directly read with user.i instead of user.call.i.
I think I'm asking for the impossible, but I am constantly surprised at the witchcraft of stackoverflow answers, so I thought I'd ask just to see if there actually was a remedy for this.
You could always enforce the 'can't delete via base class pointer' constraint that you mentioned (to some extent) by making the destructor protected in the base class:
i.e.
// Not deletable unless a derived class or friend is calling the dtor.
struct Callback {
int i;
float f;
protected:
~Callback() {}
};
// can delete objects of this type:
struct SimpleCallback : public Callback {};
struct UserInfo : public Callback {
std::string thekicker;
// ...
};
As others have mentioned, you can delete the assignment operator. For pre-c++11, just make an unimplemented prototype of that function private:
private:
UserInfo& operator=(const Callback&);
struct UserInfo : Callback {
...
// assignment from Callback disallowed
UserInfo& operator=(const Callback&) = delete;
...
};
Note that the STL features a lot of inheritance without a virtual destructor. The documentation explicitly states that these classes are not designed to be used as base classes.
some examples are vector<>, set<>, map<> ....
Another approach is to consider private inheritance while providing an accessor method to reveal the Callback (in which case you may as well use encapsulation which is cleaner).
Yes, there's trickery you can use to keep the members in sync and update operator= automatically. It's ugly though, involving macros and an unusual way of using an include file.
CallBackMembers.h:
MEMBER(int, i)
MEMBER(float, f)
Elsewhere:
struct Callback {
#define MEMBER(TYPE,NAME) TYPE NAME;
#include "CallbackMembers.h"
#undef MEMBER
};
struct UserInfo {
#define MEMBER(TYPE,NAME) TYPE NAME;
#include "CallbackMembers.h"
#undef MEMBER
std::string thekicker;
void print(); // you can use the macro trick here too
UserInfo& operator=(const Callback& rhs)
{
#define MEMBER(TYPE,NAME) NAME = rhs.NAME;
#include "CallbackMembers.h"
#undef MEMBER
return *this;
}
};
There is no way to meet ALL the criteria you want.
Personally I think your idea to make it a member and then use user.call.i is the best and most clear option. Keep in mind that you write code that uses this just once, but you make up for it in maintainability (since your UserData never has to change) and readability (since it's 100% transparent to the end-use which attribute are part of the callback data and which are auxiliary).
The only other option that might make sense is to use private inheritance instead, and using the attribute or function into UserData. With this you still have to add one using when new data is added to callback, but you get your desired user.i syntax for clients.
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.
I create a class like this
class myClass {
public:
int addMeOne;
void Invoked() { .... }
};
I created an object of it and used to send it to all other modules of my program by reference . Everyone used to increment the addMeOne variable by 1 . some even used to add twice but that’s not the point .
With this , now I want whenever someone alters addMeOne , my function Invoked() should get called .
Please note that the right strategy would have been that I should have allowed addMeOne to be exposed outside by some function and inside that function I could call Invoked . However , the interface cannot be altered now since this is now exposed to the all others and should not be modified. How can I correct this . ?
You have to make a method that would assign the value to the addMeOne variable, this is known as a setter method, and make the variable itself private.
There is no way to trigger a function upon changing an integer variable, I believe.
One alternative which would change the interface, but would not require changing the code outside is to define a class that would mimic the behavior of an integer, i.e. implement operator++ etc., and change addMeOne to this type.
You needv to read up on encapsulation. Without providing a locked down getter / setter interface to addMeOn there is no way to guarantee control over its use.
Don't be afraid to change the interface. It will not be a big task for anyone using it to change and they should be clear that what you are doing in changing it is to provide value for their benefit.
Should you preserve the ABI of this class, or just the syntax that its clients use?
If you can change the type of addMeOne, preserving the ability to write addMeOne++ etc, you can define a class and the relevant operators for it - then make addMeOne to be an instance of this class. Certainly, now addMeOne operators can do anything -- including invocations of some MyClass member functions.
Psuedo-code:
class Proxy
{
public:
Proxy(YourClass *parent) : parent_(parent), value_(0)
{}
void operator++()
{
++value_;
// doAnything with parent_
}
// accessors, cast operators etc...
private:
YourClass *parent_;
int value_;
};
class YourClass
{
public:
YourClass() : addMeOne(this)
{}
Proxy addMeOne;
};
Really, it's probably worth telling all clients to use a method instead of a public variable. You either need to change the class, the clients or both.
There's no way around it. Do it again and do it right. Take the hit.
There are tricks: Once you expose a member variable one thing that you can do is to replace int addMeOne with some other variable with the same name but a different type. countedint addMeOne. The countedint class you would have to write such that it behaves like an int but that the assignment, incrementation and so on also counts the number of times they have been used. For example
countedint & operator ++(){
m_value++;
m_number_of_uses++;
return *this;
}
countedint & operator --(){
m_value--;
m_number_of_uses++;
return *this;
}
You would probably also need to have a cast operator to int and you could count the number of uses there too.
Use can turn addMeOne into a proxy.
class myClass
{
class addMeOneProxy
{
public:
addMeOneProxy(myClass &s) : parent(s) {}
// This gets called whenever something tries to use the addMeOne
// member variable as an integer.
operator int() const
{
return parent.addMeOne;
}
// This gets called whenever something assigns a value to addMeOne.
int operator=(int val)
{
parent.Invoked();
return val;
}
// You could also implement an operator++ or whatever else you need.
private:
myClass &parent;
};
public:
void Invoked();
addMeOneProxy addMeOne;
};
Of course, if you decide to make Invoked() private at some point, you will need to make myClass a friend class of addMeOneProxy so that addMeOneProxy can call the Invoked member function.
I certainly concur with the other commenters that you should really have getter and setter functions for this, but I also understand that developers often have limited power to control and change the world they live in. So, the proxy is how you can do it if you aren't able or allowed to change the world.
I have looked at this thread on singleton class implementation, but not clear on how to use it in practice. To make the context more concrete, say I have a input stream std::istream instance that many different class need to access, but instead of passing it in for each class constructor, I am thinking of using a singleton class Connection to wrap this info. So a client can just call:
Connection.getInstance().get_input_stream();
My questions are two fold: (1) is this a proper use of singleton class (2) on implementing this, I have tried something like this:
class Connection {
public:
static Connection& getInstance() {
static Connection instance; // Guaranteed to be destroyed
return instance;
}
std::istream& get_istream() {
return is;
}
void set_istream(std::istream & stream) {
is = stream;
}
private:
std::istream& is;
}
First this code doesn't compile for some reason. Second it feels awkward that you have to call set_istream() before it is usable. Is there a better way to get this done? Thanks.
EDIT: Apparently, trying to assign a reference is my silly doing, as many of you pointed out. The second part is how to pass in stream information into singleton - it seems not worth it, which suggests this might be a wrong case for using it. thanks you all for your answers.
A reference can't be modified after creation, so to "set" the istream, you'd have to pass it to the ctor:
class Connection {
/* ... */
Connection(std::istream & stream) : is(stream) {}
private:
std::istream& is;
}
That raises a problem, however, of how you pass the correct stream to the ctor when you're creating a static instance -- and the answer to that is that it's non-trivial (at best). You could use a pointer instead of a reference, so you can create an object and point it at an actual stream later, but at that point you're basically asking for trouble (requiring two-stage initialization).
Ultimately, it's just not worth it. My advice would be against using singleton in this case at all. It looks like it's adding quite a bit of work, and providing little (if anything) in return.
Quite a few people are starting to advise against using singletons at all, at least in C++, and quite frankly, I tend to agree most of the time. This kind of situation is why -- you usually end up with little in return for the work you do on it.
I've always been told to avoid singletons, so there's two parts to this:
class Connection {
public:
static std::istream& getInstance() {
assert(is);
return *is;
}
static void set_istream(std::istream & stream) {
is = &stream;
}
private:
static std::istream* is;
}
std::istream* Connection::is = NULL;
int main() {
Connection::set_istream(std::cin);
Connection::getInstance() << "moomoomoo\n";
}
Note I made the stream static, a pointer, and global (so it's actually a singleton. Your code.... wasn't. There's no reason to have that many references laying around, and if you have is = blah where is is a reference, that does not reseat the reference. It would copy the right to the left, which for streams, doesn't make sense and wouldn't even compile.
Of course, singletons are bad. Use globals, or non-singletons. (This is a global, which is only creatable once)
//params are ignored after first call
template<typename... Ts>
std::istream& Connection(Ts... Us) {
static std::ifstream c(std::forward<Ts>(Us)...);
return c;
}
int main() {
//construct and use
Connect("input.txt") << "thing" << std::endl;
Connect() << "stuff";
Connect("this is ignored") << "IM A COW STOP SAYING IM A DUCK";
}
It doesn't compile for two reasons. First you have a very minor problem with the calling syntax. Fix it like this:
Connection::getInstance().get_input_stream();
Second is that you can't assign to a reference, it must be initialized at construction time. Since your constructor is called from the middle of getInstance, that's impractical. Use a pointer instead.
Yes it's awkward to need to call set_istream before your singleton is usable, but that seems unavoidable.