Check if std::move is done on container - c++

Is there any way I can check is std::move done on some STL container?
I have two types of classes (lets say A and B), they keep (some) instances of another class in their internal container. If instance of A keeps instance of B in it's container, that instance of B have to keep the same instance of A in it's container, too.
A can see B's private methods (B has it as it's friend), but I have to implement move constructor on B. As B can see both's internal container, I've implemented B does all adding and removing for both classes.
Problem is:
I have to implement move constructor for A, and use stl::move on that container. After container is moved to new instance of an A, only way to notify B of detachment of old class is through the method that uses B's, and old A's container and does removing for both of classes.
Is there any way for B to know that old A's container is moved and it shouldn't acces it?
It works without checking, but as class doesn't have defined state after std::move, I shouldn't call ::remove() on it (professor says it's an error).
Please note: this is my homework problem, so I wouldn't like to get illegal help of solving complete problem, only the part of checking of object's consistency to skip calling it's functions after moving it.
EDIT: added example.
IMPORTANT:
1) I'm required to use std::move. I already know an easy way to do everything in while-loop using iterators. But, std::move is explicitly required.
2) This snippet is for understanding my problem. As student, I'd like to solve it by myself, I only need info how to skip doing one line when it is not allowed.
class A;
class B {
public:
// ...... some constructors, functions and destructor.
void add(A *a) {
// .. adds to both containers.
};
void remove(A *a) { // I need to remove from both containers at most of the times
a_container.erase(a);
a->b_container.erase(this); // PROBLEM(!!): after doing std::move(b_container) I shouldn't do this! How to check is b_container moved?
};
private:
std::_______<A*> a_container; //type of container is not important
};
class A {
friend class B;
public:
// ...... some constructors, functions and destructor.
A(A && a) :
b_container(std::move(a.b_container)) {
//..
for (B *b : b_container) {
b->add(this); //adds to B's connected to the old instance
a.remove(*b); //I need somehow to disconect old B's from pointer of moved A.
}
};
void add(B & b) {
b.add(this);
};
void remove(B & b) {
b.remove(this);
};
private:
std::_______<B*> b_container; //type of container is not important
//...
};

Is there any way I can check is std::move done on some STL container?
The std::move template does not move anything, it is only
obtains an rvalue reference to its argument and converts it to an
xvalue.
If the code similar to b_container(std::move(a.b_container)) is compiled then the std::move "works" and the b_container has a move constructor and the move constructor moves internals of the object specified as the parameter. Otherwise code is not compilable. The following example is not compilable due to missing move constructor. Here it is on coliru.
#include <utility>
class B {
public:
B() = default;
B(B &&) = delete;
};
int main() {
B b0;
B b1(std::move(b0));
return 0;
}
Summarizing above text. std::move "works" always.
The state of a moved object is unspecified. Link#00 and Link#01 explain this behavior.
Is there any way for B to know that old A's container is moved and it shouldn't access it?
There is no way to check either the old container is moved or not, i.e. to check it is state. But it is possible to access it, for instance, to call the std::vector::empty method, because the object is valid. See this link for explanations.

Related

Mutual class references in C++

There's some code at my company that takes the following form:
class ObjectA {
public:
ObjectA(ObjectB &objectB): objectB(objectB) { }
void Initialize() { ... }
private:
ObjectB &objectB;
};
class ObjectB {
public:
ObjectB(ObjectA &objectA): objectA(objectA) { }
void Initialize() { ... }
private:
ObjectA &objectA;
};
Basically, two classes have a mutual dependency on the other.
This in itself isn't what bothers me, (although it's not great design IMO), it's that the mutual dependencies are passed through the constructor by reference in both situations.
So, the only way to actually construct this pair of objects (they are both required in the application) is to pass an incomplete reference as a dependency. To account for this, the separate Initialize methods are added as a 2nd stage constructor which are then called after both objects are created. Consequently, the constructors often times do nothing except assign the constructor parameters to the object internals, and initialize everything in the Intizialize method.
Although the code may be valid, my inclination is that this is a fundamentally flawed design for the following reasons:
The state of a dependent object can't be guaranteed in the
constructor
It requires the developers to make an additional call to Initialize
It precludes the use of compiler warnings that check if member variables have been initialized
There's nothing preventing Initialize from being called multiple times, which can result in strange, hard to track down errors
My coworkers tell me that having a separate initialize method simplifies the object construction since the developer doesn't have to worry about what order objects are declared in the application root. They can be declared and constructed in completely arbitrary order since everything is guaranteed to be valid once Initialize gets called.
I've been advocating that object construction should follow the same order of the dependency graph and that these objects should be redesigned to remove the mutual dependency, but I wanted to see what the SO gurus had to say about it. Am I wrong to think this is bad practice?
Edit:
The way these classes actually get constructed is through a factory class like below:
Factory {
public:
Factory():
objectA(objectB),
objectB(objectA) {
}
private:
ObjectA objectA;
ObjectB objectB;
};
This is bad practice yes. Passing a reference to objectB for objectA to work with while it's not properly initialized yet is a no-no.
It might be standard compliant and safe code now because ObjectA doesn't try to access the passed reference to ObjectB in its constructor but that safety is hanging by a thread. If later on someone decides to just initialize in the constructor or access anything from objectB, or change it any other way where objectB will be used you end up with UB.
This sounds like a use case for pointers that are reseated after both constructors have run.
I too don't like the code as posted - it is unnecessarily complicated and fragile. There is usually some concept of ownership when two classes cooperate like this, so, if objects of type A own objects of type B (which they probably should), then you would do something like:
#include <memory>
class A;
class B
{
public:
B (A& a) : a (a) { }
private:
A& a;
};
class A
{
public:
A () { b = std::make_unique <B> (*this); }
private:
std::unique_ptr <B> b;
};
Live demo

Using init-methods to avoid allocating object using new - is this bad design?

I have recently started using init methods instead of passing parameters to the constructor when designing classes in C++:
Class A {
public:
A();
init(int number);
...
};
Instead of:
Class A {
public:
A(int number);
};
This allows me to use A as a member in other classes like this:
class B {
A m_a;
};
Instead of the way I used to do it:
class B {
A *m_a;
};
(and then allocate m_a in B's constructor.)
The good thing about using init functions is that I don't have to worry about deleting m_a since it will be destroyed when the instance of B is destroyed.
My question is: Is there any downside to using init-methods that I should know about? Will this overflow the stack etc?
Everything is working fine so far, but I thought that I should ask before I write to much code in this way.
It's a horrible pattern.
The object will be in an undefined state between its construction and your calling init. Also you have to think about making init thread safe, along with making init robust if called more than once.
Also note that you can call a constructor from another one from c++11 onwards. So the argument that an init function eliminates duplication of code that could arise from having multiple constructors no longer applies.
You're not obliged to use pointers to have class instances as attributes.
Class B {
public:
explicit B(int i); // notice the explicit, btw
A m_a;
};
B::B(int i)
: m_a(i) { // will call the constructor of "A" with "i" as argument
}
m_a will be destroyed when the instance of B is destroyed too.
By adding an init method, you're defeating the purpose of constructors: you can have an object that's not fully built. Instead of forgetting to delete m_a, you take the risk to forget to init it.
You can store properties by value even if you need non-default constructor to instantiate them. In the constructor of class B you'll need to explicitly instantiate the m_a via intialization list, e.g. B(int number):m_a(number){}. Using initialization functions to overcome this "problem" is really unnecessary here as the language supports this natively.

Private constructor inhibits use of emplace[_back]() to avoid a move

Consider the following code:
#include <vector>
class A
{
public:
A(A&&); // somewhat expensive
static std::vector<A> make_As()
{
std::vector<A> result;
result.push_back(A(3));
result.push_back(A(4));
return result;
}
private:
A(int); // private constructor
};
Since A's move constructor is somewhat expensive (for whatever reason), I'd like to avoid calling it and use emplace_back() instead:
#include <vector>
class A
{
public:
A(A&&); // somewhat expensive
static std::vector<A> make_As()
{
std::vector<A> result;
result.emplace_back(3);
result.emplace_back(4);
return result;
}
private:
A(int); // private constructor
};
Unfortunately, with emplace_back(), the actual constructor call is done by something in the standard library, which is not privileged enough to be able to call A's private constructor.
I realize that there's probably little that can be done about this, but nonetheless I feel that since the calls to emplace_back() occur within a member of A, they ought to be able to call the private constructor.
Are there any workarounds for this?
The only thing I can think of is to add a friend-declaration to A, but the precise class that needs to be A's friend (that is, the class that actually tries to invoke the constructor) is implementation-specific (for example, for GCC it's __gnu_cxx::new_allocator<A>). EDIT: just realized that such a friend declaration will allow anyone to emplace_back() A's constructed with the private constructor into a container of A's, so it wouldn't really solve anything, I might as well make the constructor public at that point...
UPDATE: I should add that A's move constructor being expensive is not the only reason to avoid having to call it. It may be that A is not movable at all (nor copyable). That would not work with vector, of course, (because emplace_back() may have to reallocate the vector), but it would with deque, which also has a similar emplace_back() method but does not have to reallocate anything.
One possible workaround (or kludge) would be to use a helper class to hold the parameters to the private ctor of A (let's call this class EmplaceHelper). EmplaceHelper should also have a private ctor, and it should be in mutual friendship with A. Now all you need is a public ctor in A that takes this EmplaceHelper (via const-ref, probably), and use that with emplace_back(EmplaceHelper(...)).
Since EmplaceHelper can only be constructed by A, your public ctor is still effectively private.
It might even be possible to generalize this idea with a templated EmplaceHelper (possibly using std::tuple to hold the ctor parameters).
Edit: actually, it seems I overcomplicated this as a comment below from GManNickG gave me a simpler idea: add a private helper class (private_ctor_t in the example) that is just an empty class but since it is private it is only accessible by A. Modify A's constructor to include this private class as the first (or last) parameter (and make it public). The effect would be that only A could construct itself as if it had a private constructor, but this construction could be easily delegated now.
Like this:
#include <vector>
class A
{
private:
struct private_ctor_t {};
public:
A(private_ctor_t, int x) : A(x) // C++11 only, delegating constructor
{}
A(A&&) { /* somewhat expensive */ }
static std::vector<A> make_As()
{
std::vector<A> result;
result.emplace_back(private_ctor_t{}, 3);
result.emplace_back(private_ctor_t{}, 4);
return result;
}
private:
A(int) { /* private constructor */ }
};
If delegated constructors are not available, you can either factor out the common code for each version, or just get rid of A(int) altogether and only use the new version.
By the C++11 standard, all of the standard containers should use the allocator::construct method to do in-place construction. As such, you could simply make std::allocator a friend of A.
I suppose technically this function is allowed to delegate the actual construction call to something else. Personally, I think the spec should be a little more strict about enforcing exactly which objects call constructors and what can and cannot be delegated.
If such delegation occurs, or for whatever reason, you could provide your own allocator that forwards all calls to std::allocator except for construct. I don't suggest the latter, as many standard container implementations have special code for dealing with std::allocator that allows them to take up less space.
just realized that such a friend declaration will allow anyone to emplace_back() A's constructed with the private constructor into a container of A's, so it wouldn't really solve anything, I might as well make the constructor public at that point...
Then you're going to have to decide what's more important to you: in-place construction, or hiding privates. By it's very nature, in-place construction means that someone not in your code is doing the construction. Therefore, there's no way around it: some external code must be named a friend or the constructor must be public. In short, the constructor must be publicly accessible to whomever is delegated the construction.
Let's simplify a bit. The following fails to compile, because V has no access to A's private constructor.
struct V
{
E(int i)
{
// ...
auto a = A(i);
// ...
}
};
Going back to your code, V is just a simplification of vector, and V::E is just a simplification of what emplace_back does. vector doesn't have access to A's private constructor, and vector::emplace_back needs to call it.

C++: How to manage object lifetimes and dependencies?

A concrete problem:
I have a Main application which has objects of type A and type B (among other types).
Object of type B requires A object to be properly constructed (so there is a constructor
A(const B& b). However Main may change B object it holds at any time. How do I make
sure that when Main changes its B object then the A object's internal reference is changed ?
In general, what are some good practices to manage object lifetimes, where objects
have dependencies ?
If A never caches any of B properties, and always references the instance of B it holds to generate any dependent output, any changes that are made to B should be reflected in subsequent calls to A. I am assuming you're simply storing a reference to B within the constructor and not creating a local copy.
If I understand correctly, you want to not just change the B object but completely replace it with a different B. References can't be changed once created, so you'll want to use pointers instead.
You may want to use the Observer Pattern to let the A objects know when their B should be replaced: http://en.wikipedia.org/wiki/Observer_pattern
In general: Always make sure you know about the ownership. Whenever you create an object, wither another object needs to be the owner or it has to be a local variable. In your case the main routine would be the owner of the instance to B. If you have a reference to B in your A instance, A will see all changes to the instance - just make sure you do not copy (not having a reference does implicit copying). So in your code you would have something like
private:
const B& theReference;
or
private:
B& theReference;
if you need to call non-const methods (remember to also change your constructor in that case).
If I understood you correctly, if you make modifications to an object that main holds, it should in turn effect the object what A holds. For this you may take the help of constructor initializer.
#include <iostream>
class B{
public:
int num ;
B(int arg):num(arg) {}
};
class A{
public:
const B& ref ;
A( const B& arg ): ref(arg){}
};
int main()
{
B objOne(10) ;
A objTwo(objOne) ;
std::cout << objTwo.ref.num << std::endl ;
objOne.num = 20 ;
std::cout << objTwo.ref.num << std::endl ;
}
Output :
10
20
Keep in mind:
All problems can be solved with one more layer of indirection.
Object ownership must be obvious.
In your case, if the B instance can come-and-go at any time (the old instance is deleted, a new one is "newed"), then you can create a "utility handle" class that "wraps" the B instance:
class BHandle {
B* b_; // can change at any time
public:
....
};
Then, your A class would reference a BHandle instance, or wholly contain a BHandle instance. Then, B instances can come-and-go, but A::my_b_handle_ would always reflect where the "current" B instance is.
On the other hand, if the B instance merely has data members that change (its instance itself does not come-and-go), then you don't need to do anything (A will always reference the same B instance, and you may in some cases merely need to "notify" A that properties changed in the B object it references).
Here's how I handled the problem. User code looks like this:
class Env
{
public:
Env();
~Env();
private:
void *priv;
};
class MyInterface
{
public:
MyInterface(Env &e) : e(e) { }
int create_A();
void use_A(int a);
private:
Env &e;
void *priv;
};
int main()
{
Env e;
MyInterface i(e);
int a = i.create_A();
use_A(a);
}
This way every dependency is visible in the user code. The dependencies between objects are nicely stored inside a std::vectors in a Env class. Indexes to the vectors will be returned from the functions. create_A() and use_A() can communicate via ints. The objects will all be destroyed at the same time when Env class goes out of the scope. Your objects could be deriving from a base class which has virtual destructor.
If you have more than one int, recommended way is this:
struct ID { int i; };
Implementation of the interface would rely on the following functions:
A *find_a(const Env &e, ID i);
ID create_a(Env &e, A *ptr);
The above approach solves the following problems with object lifetimes:
lifetime of the objects
dependencies between the objects (via ints)
identifying the objects
the dependencies could be stored either via int's or via pointers
destroying the objects when lifetime ends

Declare default parameter circular reference without pointers?

Is there any way to declare these classes in a header file without indirection?
// Forwards declaration of B
class B;
class A
{
public:
// Default parameter referring to B. May return its parameter
const B& func(const B& b = B());
};
class B
{
public:
// B ctors
B() {}
B(const B&) {}
// B has A as a member
A a;
};
Visual C++ 2008 tells me with this:
error C2514: 'B' : class has no constructors
and points to the forward declaration of B ("class B;") and obviously can't see B's constructors below. A can't follow B because B contains A as a member.
If indirection must be used, what's the best way? Perhaps in C++0x B's A could be a unique_ptr member? Or maybe there's a boost class purely to sidestep this issue?
Instead of a default parameter declare two overloads, one that takes a B by reference and one that takes no parameter. In the one that takes no parameter, call the other with B(), which will work because that method can be defined after B is defined.
...
void func();
void func(const B& b);
};
class B...
void A::func() { func(B()); }
void A::func(const B&) { }
Update:
func() returns a const B&...
That's probably not a good idea. With that definition, something like:
const B& foo = a.func();
foo.bar();
would cause the dreaded "undefined behavior" (i.e., crash) because the B to which you have a reference will be destroyed as soon as the first statement is complete. Returning things other than class members by reference is usually a bad idea.
If you really want to do this, then I think you're stuck with forcing the caller to explicitly pass in B(), that is have no default parameter.
a.func(B()).bar();
(This is the only way to avoid undefined behavior with such a function.)
Of course you could just return a copy instead of a reference, but I presume you have a reason for not doing that.
Depending on what you're doing you may be able to set up better semantics using a smart pointer like shared_ptr instead of references so that you can effectively ignore the lifetimes of the objects. You then have to start being careful of reference cycles instead, however.
I can't tell what you're trying to use this for, but you might want to have a look at some Design Patterns to see if there is an established best-practice for it. You may find that this little problem is a symptom of an unfortunate choice of class structure or containment.