Object initializtion - c++

I've seen the following code snippet: test() function output is 6
#include <iostream>
using namespace std;
int z = 0;
class A{
public:
int a = 2;
A(){
a = 1;
z++;
}
A(const A& aa){
a = 3;
z += 2;
}
A& f(){return *this;}
};
void test(){
{A a, b(a), c(A().f());}
cout << z;
}
int main()
{
test();
return 0;
}
I understand what happens in all lines except object c initialization: c(A().f())? I'd would be glad, if you explain me this line?

The lines breaks down like this:
A a; // Calls A::A(); (Default constructor. Has `z++;`, so `z` is now 1)
A b(a); // Calls A::A(const A&); (Copy constructor. `z += 2;`, so `z` is now 3)
A c(
A() // Calls A::A(); (`z++;`, `z` is now 4)
// This creates a temporary `A` object
.f() // Just returns `*this`, the temporary. No copy made, nothing happens to `z`
); // Calls A::A(const A&); (`z += 2;`, `z` is now 6)

Related

c++ : Whats difference in "catching reference in value" vs "catching value in value" during function return?

What exactly happens at 1 & 2 internally , when we have assigned by return reference?
Class A
{
A& operator= (const A &ax)
{
return *this;
}
}
int main()
{
A a;
A b;
b = a; // -------------- 1
A c = a; // ----------- 2
}
// ---------------------------------------------------------------
What difference will happen in below (assigned returned value)? :
Class A
{
A operator= (const A &ax)
{
return *this;
}
}
int main()
{
A a;
A b;
b = a; // -------------- 3
A c = a; // ----------- 4
}
There is also principal mistake, because operator= made private and code is ill-formed, but this would be corrected by adding public: access modifiers.
operator= is invoked from object stored to b variable, so this variant of assignment should not perform assignment at all.
#include <iostream>
class A
{
public:
float a1;
A& operator= (const A &ax)
{
return *this;
}
};
int main()
{
A a;
a.a1 = 3;
A b;
b.a1 = 5;
b = a; // -------------- 1
std::cout << b.a1; // outputs 5
A c = a;
std::cout << c.a1; // outputs 3
}
The line
A c = a;
is called initialization and doesn't use operator=, instead it uses (generated by compiler) copy constructor, which does a shallow copy of object.
Your mistake is that member operator= meant to assign its argument's value to this. operator= return result of assignment, which can be used for chaining: a=b=c;
A& A::operator= (const A &right)
is equivalent of
A& operator= (A &left, const A &right)

Implementing Copy Constructor

I am attempting to add a copy constructor to each in order to run the main function. What I have implemented right now currenrtly prints out "b2.valuea = -858993460 b2.valueb = 10" So it reads valueb correctly but obviously something is going wrong with valuea. Advice?
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
int valuea;
public:
int getValuea() const { return valuea; }
void setValuea(int x) { valuea = x; }
// copy constructor
A() {}
A(const A& original)
{
valuea = original.valuea;
}
};
class B : public A
{
int valueb;
public:
int getValueb() const { return valueb; }
void setValueb(int x) { valueb = x; }
// copy constructor
B(){}
B(const B& original)
{
valueb = original.valueb;
}
};
int main()
{
B b1;
b1.setValuea(5);
b1.setValueb(10);
B b2(b1);
cout << "b2.valuea = " << b2.getValuea() << "b2.valueb = " <<
b2.getValueb() << endl;
}
You are not calling the copy constructor of your base-class in your derived copy constructor.
Change it like:
B(const B& original) : A(original){
valueb = original.valueb;
}
And it will output
b2.valuea = 5
b2.valueb = 10

unexpected output in copy constructor in the following code

#include < iostream >
using namespace std;
class A
{
public:
int x;
A(int i)
{
x= i;
cout<<"Constructor is Called "<<x<<endl;
}
~A()
{
cout<<"destructor is Called "<<x<<endl;
}
A(const A &a)
{
cout<<"in copy constructor a.x = "<<a.x<<endl;
cout<<" x = "<<x<<endl;
}
};
const A &fun(int i)
{
cout<<"in Fun"<<endl;
A t(i+1);
return(t);
}
main()
{
A *gg = new A(5);
A t = fun(2);
}
output of this is :
Constructor is Called 5
in Fun
Constructor is Called 3
destructor is Called 3
in copy constructor a.x = 0
x = 4067272
Why it is a.x=0 and x= 4067272?
Add code to initialize x in the copy constructor.
A(const A &a) : x(a.x)
//^^^^^^^^^^^^^^^ Missing code
{
cout<<"in copy constructor a.x = "<<a.x<<endl;
cout<<" x = "<<x<<endl;
}
Also,
fun returns a reference to a local variable. The reference is invalid after you return from fun. When you use A t = fun(2);, you are entering UB territory. You can't assume anything reasonable from it.
You can fix this by returning an object from fun instead of a const&.
A fun(int i)
{
cout<<"in Fun"<<endl;
A t(i+1);
return(t);
}

assignments operator between father and son

I have the next classes.
in the main I have 2 kinds of assignments operator (A=A and B=B).
I'm trying to get the main working, so I tried:
class A { // assume that this class is abstract
public:
virtual void assignment(const A& num) = 0;
void operator=(const A& num) { assignment(num); }
void func() = 0; // the class is abstract
};
class B: public A {
int i;
public:
void assignment(const B& num) { i = num.i; }
B& operator=(const B& num) { i = num.i; }
void func() { cout << "hello!\n"; }
};
int main()
A* a1 = new B(7); //assume I have it
A* a2 = new B(6); //assume I have it
B b1(2);
B b2(4);
*a1 = *a2; // implement an assignment operator
b1 = b2; // implement an assignment operator
}
but I got some errors that tell me that B is an abstract class and then the copy constructor doesn't work
any help appreciated!
Ok, now I see what the problem is:
void assignment(const B& num) { i = num.i; }
should be:
void assignment(const A& num) { ... }
However, we now have a problem: num which is of type A does not have a member variable i. So we need to ensure that num is actually of class B. The ... part in the above now turns into:
B& b_num = dynamic_cast<B&>(num);
i = num.i;
Note however that dynamic_cast may throw an exception if you are trying to convert some other type to B& than B.

local classes c-ism

Only first pair of values output on running this program seem correct, the others don't. What is going on?
#include <iostream>
#include <vector>
class a
{
public:
class b
{
public:
a* parent;
void test()
{
std::cout<<parent->value<<std::endl;
}
} b1;
unsigned long value;
a()
{
b1.parent = this;
value = 2;
}
void go()
{
value++;
b1.test();
}
};
int main()
{
{
a a1;
a1.go();
std::cout<<a1.value<<std::endl;
}
std::cout<<std::endl;
{
a a1; a1 = a();
a1.go();
std::cout<<a1.value<<std::endl;
}
std::cout<<std::endl;
{
std::vector<a> a1; a1.push_back(a());
a1.at(0).go();
std::cout<<a1.at(0).value<<std::endl;
}
return 0;
}
You are missing a copy ctor and assignment operator for type 'a'. When copying or assigning objects, you consequently don't properly update their b1.parent. Instead, the b1.parent values point to a different 'a' object than their real parent.
To see this problem in action, use this in your existing code:
void go() {
value++;
std::cout << (this == b1.parent ? "as expected\n" : "uh-oh\n");
b1.test();
}
To fix it, modify class a:
a() : b1 (this), value (2) {} // a change from your default ctor
a(a const &x) : b1 (this), value (x.value) {}
a& operator=(a const &x) {
value = x.value;
return *this;
}
And modify class b (necessarily to use the ctor initializer as I do above):
b(a *parent) : parent (parent) {}