Change 'this' pointer of an object to point different object - c++

class C{
//methods and properties
}
void C::some_method(C* b){
delete this;
this = b;
}
This gives me follwing error when compiling:
error: lvalue required as left operand of assignment
My intention:
Say there are objects a and b of class C. The contents of the class C can be very huge and field by field copying can be very costly. I want all the contents of 'a' to be replaced by 'b' in an economical way.
Will default copy constructor do the intended task?
I found something called 'move constructor'
http://akrzemi1.wordpress.com/2011/08/11/move-constructor/
Perhaps, it might get the effect that I want.

The this-pointer is an implicit pointer to the object in whose context you are working, you cannot reassign it.
According to Stroustrup's bible (The C++ Programming Language, 3rd edition I have) this is expressed as
C * const this
meaning you have a constant pointer to your class C, so the compiler will complain if you try to change it.
EDIT:
As I was corrected, the above mentioned expression does not describe this fully correctly, for this is actually an rvalue.

You cannot change what this points to. I would also not know why you'd want to do this.

To quote the standard:
In the body of a non-static (9.3) member function, the keyword
this is a prvalue expression whose value is the address of the
object for which the function is called.
A "prvalue" is a pure rvalue, something like 42 or 3.14159.
In the same way you can't do something like 42 = x, you can't
assign to this; in both cases (at least conceptually), there
is no object whose value can change.
And I'm really curious as to what you expect to happen if
I write something like:
int
main()
{
C c1;
C c2
c1.some_method( &c2 );
}
Do you expect the address of c1 to somehow miraculously
change, and for c1 and c2 to be aliases to the same object?
(And c1.some_method( NULL ) is even more intreguing.)

You can't assign a different value to this as it point to the object itself, and this haven't any sense.
You could instantiate a new object and use its implicit this pointer instead.
Moreover, if you try to make a copy of object, you can overwrite operator=
class Foo
{
public:
[...]
Foo& operator=(const Foo& foo);
}
int main()
{
Foo foo;
foobar = foo; //invoke operator= overwrited method
}

The error says "You can't assign b to this". As far as I know, this is something you can't change, because it's not an actual pointer, but a self-reference.

Just use the usual approach instead of black magic and UB:
C* c1 = new C();
C* c2 = new C();
// do some work perhaps ...
delete c1;
c1 = c2;
Now c1 is an alias to c2 as you wanted. Be careful though when cleaning up memory so you don't end up deleting an object twice. You might perhaps consider smart pointers...

Related

calling copy constructor and operator= for class data members

Below is an example code (for learning purpose only). Classes A and B are independent and have copy contructors and operators= .
class C
{
public:
C(string cName1, string cName2): a(cName1), b(new B(cName2)) {}
C(const C &c): a(c.a), b(new B(*(c.b))) {}
~C(){ delete b; }
C& operator=(const C &c)
{
if(&c == this) return *this;
a.operator=(c.a);
//1
delete b;
b = new B(*(c.b));
//What about this:
/*
//2
b->operator=(*(c.b));
//3
(*b).operator=(*(c.b));
*/
return *this;
}
private:
A a;
B *b;
};
There are three ways of making assignment for data member b. In fact first of them calls copy constructor. Which one should I use ? //2 and //3 seems to be equivalent.
I decided to move my answer to answers and elaborate.
You want to use 2 or 3 because 1 reallocated the object entirely. You do all the work to clean up, and then do all the work to reallocate/reinitialized the object. However copy assignment:
*b = *c.b;
And the variants you used in your code simply copy the data.
however, we gotta ask, why are you doing it this way in the first place?
There are two reasons, in my mind, to have pointers as members of the class. The first is using b as an opaque pointer. If that is the case, then you don't need to keep reading.
However, what is more likely is that you are trying to use polymorphism with b. IE you have classes D and E that inherit from B. In that case, you CANNOT use the assignment operator! Think about it this way:
B* src_ptr = new D();//pointer to D
B* dest_ptr = new E();//pointer to E
*dest_ptr = *src_ptr;//what happens here?
What happens?
Well, the compiler sees the following function call with the assignment operator:
B& = const B&
It is only aware of the members of B: it can't clean up the no longer used members of E, and it can't really translate from D to E.
In this situation, it is often better to use situation 1 rather than try to decern the subtypes, and use a clone type operator.
class B
{
public:
virtual B* clone() const = 0;
};
B* src_ptr = new E();//pointer to D
B* dest_ptr = new D();//pointer to E, w/e
delete dest_ptr;
dest_ptr = src_ptr->clone();
It may be down to the example but I actually don't even see why b is allocated on the heap. However, the reason why b is allocate on the heap informs how it needs to be copied/assigned. I think there are three reasons for objects to be allocated on the heap rather than being embedded or allocated on the stack:
The object is shared between multiple other objects. Obviously, in this case there is shared ownership and it isn't the object which is actually copied but rather a pointer to the object. Most likely the object is maintained using a std::shared_ptr<T>.
The object is polymorphic and the set of supported types is unknown. In this case the object is actually not copied but rather cloned using a custom, virtual clone() function from the base class. Since the type of the object assigned from doesn't have to be the same, both copy construction and assignment would actually clone the object. The object is probably held using a std::unique_ptr<T> or a custom clone_ptr<T> which automatically takes care of appropriate cloning of the type.
The object is too big to be embedded. Of course, that case doesn't really happen unless you happen to implement the large object and create a suitable handle for it.
In most cases I would actually implement the assignment operator in an identical form, though:
T& T::operator=(T other) {
this->swap(other);
return *this;
}
That is, for the actual copy of the assigned object the code would leverage the already written copy constructor and destructor (both are actually likely to be = defaulted) plus a swap() method which just exchanges resources between two objects (assuming equal allocators; if you need to take case of non-equal allocators things get more fun). The advantage of implementing the code like this is that the assignment is strong exception safe.
Getting back to your approach to the assignment: in no case would I first delete an object and then allocate the replace. Also, I would start off with doing all the operations which may fail, putting them into place at an appropriate place:
C& C::operator=(C const& c)
{
std::unique_ptr tmp(new B(*c.b));
this->a = c.a;
this->b = tmp.reset(this->b);
return *this;
}
Note that this code does not do a self-assignment check. I claim that any assignment operator which actually only works for self-assignment by explicitly guarding against is not exception-safe, at least, it isn't strongly exception safe. Making the case for the basic guarantee is harder but in most cases I have seen the assignment wasn't basic exception safe and your code in the question is no exception: if the allocation throws, this->b contains a stale pointer which can't be told from another pointer (it would, at the very least, need to be set to nullptr after the delete b; and before the allocation).
b->operator=(*(c.b));
(*b).operator=(*(c.b));
These two operations are equivalent and should be spelled
*this->b = *c.b;
or
*b = *c.b;
I prefer the qualified version, e.g., because it works even if b is a base class of template inheriting from a templatized base, but I know that most people don't like it. Using operator=() fails if the type of the object happens to be a built-in type. However, a plain assignment of a heap allocated object doesn't make any sense because the object should be allocated on the heap if that actually does the right thing.
If you use method 1 your assignment operator doesn't even provide the basic (exception) guarantee so that's out for sure.
Best is of course to compose by value. Then you don't even have to write your own copy assignment operator and let the compiler do it for you!
Next best, since it appears you will always have a valid b pointer, is to assign into the existing object: *b = *c.b;
a = c.a;
*b = *c.b;
Of course, if there is a possibility that b will be a null pointer the code should check that before doing the assignment on the second line.

why use a const non-reference when const reference lifetime is the length of the current scope

So in c++ if you assign the return value of a function to a const reference then the lifetime of that return value will be the scope of that reference. E.g.
MyClass GetMyClass()
{
return MyClass("some constructor");
}
void OtherFunction()
{
const MyClass& myClass = GetMyClass(); // lifetime of return value is until the end
// of scope due to magic const reference
doStuff(myClass);
doMoreStuff(myClass);
}//myClass is destructed
So it seems that wherever you would normally assign the return value from a function to a const object you could instead assign to a const reference. Is there ever a case in a function where you would want to not use a reference in the assignment and instead use a object? Why would you ever want to write the line:
const MyClass myClass = GetMyClass();
Edit: my question has confused a couple people so I have added a definition of the GetMyClass function
Edit 2: please don't try and answer the question if you haven't read this:
http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
If the function returns an object (rather than a reference), making a copy in the calling function is necessary [although optimisation steps may be taken that means that the object is written directly into the resulting storage where the copy would end up, according to the "as-if" principle].
In the sample code const MyClass myClass = GetMyClass(); this "copy" object is named myclass, rather than a temporary object that exists, but isn't named (or visible unless you look at the machine-code). In other words, whether you declare a variable for it, or not, there will be a MyClass object inside the function calling GetMyClass - it's just a matter of whether you make it visible or not.
Edit2:
The const reference solution will appear similar (not identical, and this really just written to explain what I mean, you can't actually do this):
MyClass __noname__ = GetMyClass();
const MyClass &myclass = __noname__;
It's just that the compiler generates the __noname__ variable behind the scenes, without actually telling you about it.
By making a const MyClass myclass the object is made visible and it's clear what is going on (and that the GetMyClass is returning a COPY of an object, not a reference to some already existing object).
On the other hand, if GetMyClass does indeed return a reference, then it is certainly the correct thing to do.
IN some compilers, using a reference may even add an extra memory read when the object is being used, since the reference "is a pointer" [yes, I know, the standard doesn't say that, but please before complaining, do me a favour and show me a compiler that DOESN'T implement references as pointers with extra sugar to make them taste sweeter], so to use a reference, the compiler should read the reference value (the pointer to the object) and then read the value inside the object from that pointer. In the case of the non-reference, the object itself is "known" to the compiler as a direct object, not a reference, saving that extra read. Sure, most compilers will optimise such an extra reference away MOST of the time, but it can't always do that.
One reason would be that the reference may confuse other readers of your code. Not everybody is aware of the fact that the lifetime of the object is extended to the scope of the reference.
The semantics of:
MyClass const& var = GetMyClass();
and
MyClass const var = GetMyClass();
are very different. Generally speaking, you would only use the
first when the function itself returns a reference (and is
required to return a reference by its very semantics). And you
know that you need to pay attention to the lifetime of the
object (which is not under your control). You use the second
when you want to own (a copy of) the object. Using the second
in this case is misleading, can lead to surprises (if the
function also returns a reference to an object which is
destructed earlier) and is probably slightly less efficient
(although in practice, I would expect both to generate exactly
the same code if GetMYClass returns by value).
Performance
As most current compilers elide copies (and moves), both version should have about the same efficiency:
const MyClass& rMyClass = GetMyClass();
const MyClass oMyClass = GetMyClass();
In the second case, either a copy or move is required semantically, but it can be elided per [class.copy]/31. A slight difference is that the first one works for non-copyable non-movable types.
It has been pointed out by Mats Petersson and James Kanze that accessing the reference might be slower for some compilers.
Lifetime
References should be valid during their entire scope just like objects with automatic storage are. This "should" of course is meant to be enforced by the programmer. So for the reader IMO there's no differences in the lifetimes implied by them. Although, if there was a bug, I'd probably look for dangling references (not trusting the original code / the lifetime claim for the reference).
In the case GetMyClass could ever be changed (reasonably) to return a reference, you'd have to make sure the lifetime of that object is sufficient, e.g.
SomeClass* p = /* ... */;
void some_function(const MyClass& a)
{
/* much code with many side-effects */
delete p;
a.do_something(); // oops!
}
const MyClass& r = p->get_reference();
some_function(r);
Ownership
A variable directly naming an object like const MyClass oMyClass; clearly states I own this object. Consider mutable members: if you change them later, it's not immediately clear to the reader that's ok (for all changes) if it has been declared as a reference.
Additionally, for a reference, it's not obvious that the object its referring to does not change. A const reference only implies that you won't change the object, not that nobody will change the object(*). A programmer would have to know that this reference is the only way of referring to that object, by looking up the definition of that variable.
(*) Disclaimer: try to avoid unapparent side effects
I don't understand what you want to achieve. The reason that T const& can be bound (on the stack) to a T (by value) which is returned from a function is to make it possible other function can take this temporary as an T const& argument. This prevents you from requirement to create overloads. But the returned value has to be constructed anyway.
But today (with C++11) you can use const auto myClass = GetMyClass();.
Edit:
As an excample of what can happen I will present something:
MyClass version_a();
MyClass const& version_b();
const MyClass var1 =version_a();
const MyClass var2 =version_b();
const MyClass var3&=version_a();
const MyClass var4&=version_b();
const auto var5 =version_a();
const auto var6 =version_b();
var1 is initialised with the result of version_a()
var2 is initialised with a copy of the object to which the reference returned by version_b() belongs
var3 holds a const reference to to the temoprary which is returned and extends its lifetime
var4 is initialised with the reference returned from version_b()
var5 same as var1
var6 same as var4
They are semanticall all different. var3 works for the reason I gave above. Only var5 and var6 store automatically what is returned.
there is a major implication regarding the destructor actually being called. Check Gotw88, Q3 and A3. I put everything in a small test program (Visual-C++, so forgive the stdafx.h)
// Gotw88.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
class A
{
protected:
bool m_destroyed;
public:
A() : m_destroyed(false) {}
~A()
{
if (!m_destroyed)
{
std::cout<<"A destroyed"<<std::endl;
m_destroyed=true;
}
}
};
class B : public A
{
public:
~B()
{
if (!m_destroyed)
{
std::cout<<"B destroyed"<<std::endl;
m_destroyed=true;
}
}
};
B CreateB()
{
return B();
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout<<"Reference"<<std::endl;
{
const A& tmpRef = CreateB();
}
std::cout<<"Value"<<std::endl;
{
A tmpVal = CreateB();
}
return 0;
}
The output of this little program is the following:
Reference
B destroyed
Value
B destroyed
A destroyed
Here a small explanation for the setup. B is derived from A, but both have no virtual destructor (I know this is a WTF, but here it's important). CreateB() returns B by value. Main now calls CreateB and first stores the result of this call in a const reference of type A. Then CreateB is called and the result is stored in a value of type A.
The result is interesting. First - if you store by reference, the correct destructor is called (B), if you store by value, the wrong one is called. Second - if you store in a reference, the destructor is called only once, this means there is only one object. By value results in 2 calls (to different destructors), which means there are 2 objects.
My advice - use the const reference. At least on Visual C++ it results in less copying. If you are unsure about your compiler, use and adapt this test program to check the compiler. How to adapt? Add copy / move constructor and copy-assignment operator.
I quickly added copy & assignment operators for class A & B
A(const A& rhs)
{
std::cout<<"A copy constructed"<<std::endl;
}
A& operator=(const A& rhs)
{
std::cout<<"A copy assigned"<<std::endl;
}
(same for B, just replace every capital A with B)
this results in the following output:
Reference
A constructed
B constructed
B destroyed
Value
A constructed
B constructed
A copy constructed
B destroyed
A destroyed
This confirms the results from above (please note, the A constructed results from B being constructed as B is derived from A and thus As constructor is called whenever Bs constructor is called).
Additional tests: Visual C++ accepts also the non-const reference with the same result (in this example) as the const reference. Additionally, if you use auto as type, the correct destructor is called (of course) and the return value optimization kicks in and in the end it's the same result as the const reference (but of course, auto has type B and not A).

Copying similar classes in C++

I have two classes with similar structure.
class A{
int a;
char *b;
float c;
A(char *str) { //allocate mem and assign to b }
};
class B{
int a;
char *b;
float c;
B(char *str) { //allocate mem and assign to b }
B(B & bref) { //properly copies all the data }
};
I want to copy an object of B to the object of A. Are the following conversions fine?
A aobj("aobjstr");
B bobj("bobjstr");
bobj = aobj; //case 1
bobj = B(aobj); //case 2
Will the case 2 work? Will aobj be properly converted and interpreted as B & when B's copy constructor gets called?
EDIT: What about?
B bobj(aobj)
No, you can't implicitly convert between unrelated types without writing conversion constructors or conversion operators. Presumably, your compiler told you this; mine gave errors such as:
error: no match for ‘operator=’ in ‘bobj = aobj’
note: no known conversion for argument 1 from ‘A’ to ‘const B&’
error: no matching function for call to ‘B::B(A&)’
You could allow the conversion by giving B a conversion constructor:
class B {
// ...
B(A const & a) { /* properly copy the data */ }
};
If you can't change the classes, then you'll need a non-member function to do the conversion; but this is probably only possible if the class members are public. In your example, all the members, including the constructors, are private, so the classes can't be used at all. Presumably, that's not the case in your real code.
If you want to live dangerously, you might be able to get away with explicitly reinterpreting an A object as a B, since they are both standard-layout types with the same data members:
// DANGER: this will break if the layout of either class changes
bobj = reinterpret_cast<B const &>(a);
Note that, since your class allocates memory, it presumably needs to deallocate it in its destructor; and to avoid double deletions, you'll also have to correctly implement both a copy constructor and a copy-assignment operator per the Rule of Three.
If that all sounds like too much work, why not use std::string, which takes care of memory management for you?
If you tried to compile it you would find that none of this works. For one thing your constructors are private.
bobj = aobj; //case 1
This tries to call an assignment operator with the signature:
B& B::operator =(A const&)
This does not exist and compilation will fail.
bobj = B(aobj); //case 2
This tries to call A::operator B(), which does not exist and compilation will fail.
Finally:
B bobj(aobj)
This tries to call a constructor with the signature B::B(A const&), which does not exist and compilation will fail.
You say,
I can't change/modify class A and B, those are generated.
Then either the generator needs to be fixed or you're going to have to write your own adaptors.
You can do this by considering the following notes:
1) char* b makes a problem. When you copy aobj to bobj, the value of pointer aobj.b will be copied to bobj.b which means that they both refer to a same memory location and changing one like this: aobj.b[0] = 'Z' will cause bobj.b to change.
You can solve this by changing b from a pointer to a flat array:
//...
char b[MAXLEN];
//...
The better solution to this is to define a constructor (accepting the other type) and overload the assignment (=) operator, at least for class B, and handle the pointer assignment (allocate buffer for the new pointer and copy content to it).
2) UPDATED: A sample syntax is like this:
bobj = B(reinterpret_cast<B&> (aobj));
// or simply:
bobj = reinterpret_cast<B&> (aobj);
3) Note that this is dangerous, not safe, and not recommended. This means that the design of your solution should probably change. For example, A and B may both inherit from a common base class; B inherits from A; or B explicitly defines a constructor and an assignment operator for class A. These are far more recommended.

How arrow-> operator overloading works internally in c++?

I understand the normal operator overloading. Compiler can translate them to method call directly. I am not very clear about the -> operator. I was writing my first custom iterator and I felt like the need of -> operator. I took a look at the stl source code and implemented my own like it:
MyClass* MyClassIterator::operator->() const
{
//m_iterator is a map<int, MyClass>::iterator in my code.
return &(m_iterator->second);
}
Then I can use an instance of MyClassIterator like:
myClassIterator->APublicMethodInMyClass().
Looks like the compiler does two steps here.
1. Call the ->() method the get a temporary MyClass* variable.
2. Call the APublicMethodInMyClass on the temp variable use its -> operator.
Is my understanding correct?
The operator-> has special semantics in the language in that, when overloaded, it reapplies itself to the result. While the rest of the operators are applied only once, operator-> will be applied by the compiler as many times as needed to get to a raw pointer and once more to access the memory referred by that pointer.
struct A { void foo(); };
struct B { A* operator->(); };
struct C { B operator->(); };
struct D { C operator->(); };
int main() {
D d;
d->foo();
}
In the previous example, in the expression d->foo() the compiler will take the object d and apply operator-> to it, which yields an object of type C, it will then reapply the operator to get an instance of B, reapply and get to A*, after which it will dereference the object and get to the pointed data.
d->foo();
// expands to:
// (*d.operator->().operator->().operator->()).foo();
// D C B A*
myClassIterator->APublicMethodInMyClass()
is nothing but the following:
myClassIterator.operator->()->APublicMethodInMyClass()
The first call to the overloaded operator-> gets you a pointer of some type which has an accessible (from your call-site) member function called APublicMethodInMyClass(). The usual function look-up rules are followed to resolve APublicMethodInMyClass(), of course, depending on whether it is a virtual or not.
There is not necessarily a temporary variable; the compiler may or may not copy the pointer returned by &(m_iterator->second). In all probability, this will be optimized away. No temporary objects of type MyClass will be created though.
The usual caveats also do apply to m_iterator -- make sure that your calls do not access an invalidated iterator (i.e. if you are using vector for example).

Variable initialization (pointer and value)

Foo f1 = Foo(); // (1) Ok
Foo f2 = Foo; // (2) Compiler error
Foo *p1 = new Foo(); // (3) Ok
Foo *p2 = new Foo; // (4) Ok. Why??
I was wondering why there exists two ways to initialize pointers. It looks a little inconsistent. Is there some logical reason, and if so, what? Or, maybe it's some kind of legacy? And if so, What is the origin of such notation?
It's a bit... complicated, to say the least.
When dealing with objects, both notations are equivalent. When dealing with primitive types (such as int), (3) will initialize (zero fill) the value, while (4) will not (the value will be left undefined).
For automatically allocated objects, this:
Foo f1;
Declares and initializes a Foo object using the default constructor. This:
Foo f2 = Foo();
Declares and initializes a Foo object using the copy constructor, essentially copying the value of a temporary object (the Foo()), which is built with the default constructor.
I give you that it seems illogical, but if you think about the possible meanings, it makes a lot of sense.
Without knowing what Foo might be, neither a human nor the compiler (here, the human perspective is more important) would be able to determine if Foo f2 = Foo; is a) creating a new temporary Foo object and copy constructing another one with it or b) assigning the value of a variable Foo to the copy constructed object (f2). It may seem obvious for us because our convention tells us that Foo must be a type as it is capitalised, but in general it is not that simple (again: this mainly applies to a human reader that does not necessarily have the whole source code memorised).
The difference between (2) and (4) is that for the latter, only one interpretation is admissible, because new var (where var is a variable) is not a legal expression.
The equivalent of 4 for scope-based resources is actually just
Foo f;
The legacy reason for the differences is essentially that in C, primitive types, such as int, were not default-initialized to something useful. C++ inherited this behaviour for performance reasons- at the time. Of course, now, it's a trivial amount of processor time to expend. In C++, they introduced a new syntax by which it would always be initialized- the brackets.
int i = int();
i is always guaranteed to be 0.
int i;
The value of i is undefined.
This is the exact same as for the pointer variety, just with some new:
int* i = new int(); // guaranteed 0
int* i = new int; // undefined