Understanding the issues of bit copying [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to understand the following code:
blueberry bitCopy(blueberry a) {
cout << "bitCopy " << blueberry::blQuantity << endl;
return a;
}
void howMany() {
cout << blueberry::blQuantity << endl;
}
int main() {
blueberry firstBl;
howMany();
bitCopy(firstBl);
howMany();
}
class blueberry:
#ifndef header_h
#define header_h
#pragma once
#include <string>
#include <iostream>
using namespace std;
class blueberry {
private:
static int blQuantity;
public:
blueberry();
~blueberry() {
blQuantity--;
}
friend blueberry bitCopy(blueberry a);
friend void howMany();
};
#endif
int blueberry::blQuantity = 0;
blueberry::blueberry() {
blQuantity++;
};
class blueberry is just some class that has a static int value blQuantity that increments in the constructor each time an object is created, and decrements in the destructor each time an object goes out of scope.
The read out from this program is:
1
bitCopy 1
-1
I was expecting 0 at the end rather than -1. Can someone explain this please?
PLEASE do not tell me I require a copy constructor. I am not trying to fix this code so that the object count works. I am instead trying to understand how this works and why the blQuantity is not the value I expect.

class blueberry is just some class that has a static int value blQuantity that increments in the constructor each time an object is created, and decrements in the destructor each time an object goes out of scope.
Are you sure that's each and every time one is created? I think there is something you've missed.
blueberry bitCopy(blueberry a)
That's pass-by-value; i.e., blueberry a here is a copy of what was submitted to bitCopy(). That invokes blueberry's copy constructor, which you have not defined. The compiler thus creates a simple one for you, which copies over any member values from the original object -- but it does NOT increment anything. If you want that, you'll have to define:
blueberry::blueberry (const blueberry&) // copy constructor
blueberry& operator= (const blueberry&) // copy assignment operator
You may also want a move constructor and move assignment operator -- see that wikipedia article about the "rule of three (or five)"
I linked in the above paragraph.
The reason blQuantity is -1 at the end is because there are actually two copies made with bitCopy(), one for the parameter and one for the return value. If you change it to:
blueberry bitCopy (blueberry &a)
I.e., using pass-by-reference, there will only be one copy and blQuantity will be 0 afterward. If you then make the return value void, there will be no copies made and blQuantity should be 1.
Here's a demonstration of the roles of the copy constructor and operator= (copy assignment operator):
#include <iostream>
#include <string>
using namespace std;
class A {
public:
string x;
A (string s) : x(s) {
cout << "A con " << "(" << x << ")\n";
}
A (const A& other) : x(other.x) {
x.append("-copy");
cout << "A copy " << "(" << x << ")\n";
}
A& operator= (const A& other) {
x = other.x;
x.append("[=]");
cout << "A assign " << "(" << x << ")\n";
return *this;
}
~A () { cerr << x << " A bye!\n"; }
};
A test (A a) {
return a;
}
int main (void) {
A a("#1");
cout << "test()\n";
A b = test(a);
cout << "Copy assign:\n";
b = a;
cout << "Exiting...\n";
return 0;
}
I'll step through the output from this:
A con (#1)
test()
A copy (#1-copy)
A copy (#1-copy-copy)
#1-copy A bye!
The first line is from A a("#1"). The last three lines are a result of A b = test(a). The first one is copying in the parameter, A test (test a). The second is the creation of the return value, which is a copy of the parameter, so the tag on the object is now #1-copy-copy. That initializes b in main(). When test() exits, the parameter object is destroyed, #1-copy A bye!.
Copy assign:
A assign (#1[=])
This is from b = a in main(). Notice that the previous version of b is not destroyed. This is because copy assignment is meant to turn one object into a copy of another; neither object is destroyed, but the contents of the target object is presumably changed, hence b's tag is now #1[=]. So predictably:
Exiting...
#1[=] A bye!
#1 A bye!
When the program ends, a and b are destroyed.
If you change the signature of test() to:
A& test (A &a)
You'll get this output:
A con (#1)
test()
A copy (#1-copy)
Copy assign:
A assign (#1[=])
Exiting...
#1[=] A bye!
#1 A bye!
Only two objects are ever created, a via the constructor and b via the copy con; both of them are not destroyed until the end. If you then do not use the return value of test(), only one object is ever created.

Related

C++ Move constructor vs Copy constructor if no RAW pointer variable is present

Learning C++ and all about constructors (Copy, Move), I am wondering what the correct/smart/efficient way would be.
The following scenario:
I have a class Movie that contains title, rating and counter. Every time I instantiate an object of that class, I want that object be placed into an array (called Movies) of objects. So if I watched 3 movies, my array would contains three instances of the class Movie. Since my movie class does not contain a RAW pointer, I am wondering if there is a difference in performance whether I use copy or move to add a particular movie into my collection. I hope my idea is clear to better understand the following code. Hopefully, someone can enlighten me. Thank you,
Mingw-w64 version 8.1.0, Win10, VSCode:
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Movie
{
private:
string movieName;
int movieRating;
int movieCounter;
public:
string getName();
Movie(string movieNameVal="None", int movieRatingVal=0);
Movie(const Movie &source);
Movie(Movie &&source);
~Movie();
};
Movie::Movie(string movieNameVal, int movieRatingVal)
: movieName(movieNameVal), movieRating(movieRatingVal) // Equivalent to movieName = movieNameVal; movieRating = movieRatingVal;
{
cout << "Constructor called" << endl;
}
// Copy constructor
Movie::Movie(const Movie &source)
: Movie(source.movieName, source.movieRating)
{
cout << "Copy constructor called" << endl;
}
// Move constructor
Movie::Movie(Movie &&source)
: movieName(source.movieName), movieRating(source.movieRating)
{
cout << "Move constructor called" << endl;
}
Movie::~Movie()
{
cout << "Destructor called" << endl;
}
int main()
{
{
vector<Movie> Movies1;
cout << "------------Movies1: Copy constructor version------------" << endl;
Movie movie1("Terminator 1", 5);
Movies1.push_back(movie1);
}
cout << endl;
cout << endl;
cout << endl;
{
vector<Movie> Movies2;
string namex = "Terminator 2";
int ratingx = 5;
cout << "------------Movies2: Move constructor version------------" << endl;
Movies2.push_back(Movie(namex, ratingx));
}
return 0;
}
You asking about the difference in performance when you append in a vector by copying or moving the object instance of your particular class.
First, you can always measure! I think the majority of time taken would go in the vector reallocating its capacity(), so when you have an idea of the number of objects that will be inserted, is always recommended to reserve() some memory.
Looking the output of your very code snippet:
------------Movies1: Copy constructor version------------
Constructor called
Constructor called
Copy constructor called
Destructor called
Destructor called
------------Movies2: Move constructor version------------
Constructor called
Move constructor called
Destructor called
Destructor called
I think I already see a winner. As said in the comments, in your particular class you may let the compiler generate the default constructors; generally the move may be more efficient than the copy (see more here).
However, consider this third possibility:
Movies3.emplace_back(namex, ratingx);
------------Movies3: emplace_back version------------
Constructor called
Destructor called
That wouldn't be so bad.

At which line is the copy constructor called?

I have a few lines of code and I don't get, why and where the copy constructor is called. Could you explain it to me?
The output is:
CS10
CS99
CC100
Obj10=Obj100
D100
Obj10=Obj99
D99
D10
This is my source code:
#include <iostream>
using namespace std;
class my
{
int m;
public:
my(int i): m(i)
{
cout << "CS" << m << endl;
}
my(const my& c): m(c.m+1)
{
cout << "CC" << m << endl;
}
~my()
{
cout << "D" << m << endl;
}
my& operator=(const my &c)
{
cout << "Obj" << m << "=Obj" << c.m << endl;
return *this;
}
};
my f(my* x)
{
return *x;
}
int main()
{
my m1(10);
my m2(99);
m1 = f(&m2); // creates a new object
m1 = m2; // does not create a new object
}
Why and where is copy constructor called causing the output CC100 and D100?
In this function
my f(my* x)
{
return *x;
}
called in statement
m1 = f(&m2); // creates a new object
the copy constructor is called to copy object *x in the return temporary object.
In fact it looks as
my tmp = *x; // the copy constructor is called
m1 = tmp;
When trying to think about when a copy constructor is called you should keep a few things in mind:
Scope - functions can't see outside of themselves and their associated namespace. If you want to pass a variable to a function you need to save it in the global environment, repush a scoped copy and then operate on it.
When you use passing by reference you operate on the global copy but since in this case you are returning the value that is pointed to and not a pointer you have to push that return value onto the stack separately because it is stored at a different temporary register address that is popped off the stack after you assign it to a permanent location in main. That's where the destructor comes in.
You made a temporary return value to pass the value out of your function so it's got to be deleted because L1, L2, and L3 cache are all prime real estate.
I highly recommend doing a little bit of reading on assembly code operations or even try compiling simple programs into assembly and seeing how the low level languages work under the hood. Cheers!

C++ Class Constructor / Destructor

I have a below code. Every time Constructor is called, I increase a counter and the counter is decreased every time Destructor is called. After instantiating three class objects, I tried printing out the counter value. Then I tried printing out the counter value again after deleting one of the objects. The expected values were 4 and 3, but instead I get 2 and 1.
I actually tried printing out something within the Constructor and Destructor to observe how many times they were actually called, but surprisingly Destructor was called several times in addition to the time when I called "delete object". Is it because the Destructor is called automatically? If so, is there any way to turn the feature off to test my code?
** The code originally has Add and Mult functions in the class, but I omitted here because the details of the functions seem irrelevant here.
#include <iostream>
using namespace std;
class Complex{
private:
double x, y;
static int count;
Complex Add(Complex como)
{
Complex t;
t.x=x+como.x;
t.y=y+como.y;
return t;
}
Complex Mul(Complex como)
{
Complex t;
t.x=(x*como.x)-(y*como.y);
t.y=(y*como.x)+(x*como.y);
return t;
}
public:
Complex(double a=0, double b=0) : x(a), y(b) {count++;}
~Complex() {count--;}
void Print() {cout << "(" << x << ", " << y << ")" << endl;}
static int GetCount() {return count;}
};
int Complex::count=0;
int main()
{
Complex com1(1.0, 2.0), com2(3.0, 4.0);
Complex com3;
com1.Print(); cout << endl;
com2.Print(); cout << endl;
com3 = com1.Add(com2); com3.Print(); cout << endl;
Complex *pcom4 = new Complex;
*pcom4 = com1.Mul(com2); pcom4->Print(); cout << endl;
cout << "#complex numbers = " << com1.GetCount() << endl;
delete pcom4;
cout << "#complex numbers = " << com1.GetCount() << endl;
return 0;
}
In C++ you can construct objects in three ways:
using the "constructor"
using the "copy constructor"
using the "move constructor"
If don't define them the compiler will automatically write the code for you (unless you stop it from doing that explicitly).
Your method Mul and Add are accepting the other complex number by value and this means that a copy constructor call will be used to copy the argument of the call.
The automatic synthesized copy constructor doesn't increment the counter.
Your methods are taking Complex objects as parameters (not references to existing objects), so new objects are being created for each call and are destroyed at the end of the call.

copy constructor not called, can someone explain how returnin values from function works [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
No call to the copy constructor
In this code copy constructor is never called (neither does move constructor, or assignment operator). How it is possible? Can someone explain how function returns values, what happens with stack and registers (or post some good link)?
#include <iostream>
#include <cstring>
using namespace std;
class Test;
Test getnew(int arg);
class Test
{
public:
char *conts;
int len;
Test(char* input = NULL){conts = new char[len=10];
if(input)strncpy(conts,input,9);else strcpy(conts,"xxxxx");
cout << "\nconstructor: " << conts;
};
Test(const Test& t){
conts = new char[10];
if(t.len)strncpy(conts,t.conts,9);
len = t.len;
cout << "\ncopy-constructor: " << conts;
};
Test(Test&& t){
conts = t.conts;
t.conts = NULL;
std::swap(len,t.len);
cout << "\nmove-constructor: " << conts;
};
~Test(){
cout << "\ndestructor";
if(conts)delete [] conts;
len = 0;
conts = NULL;
};
Test& operator=(Test rhs)
{
std::swap(conts,rhs.conts);
std::swap(len,rhs.len);
cout << "\nassigend: " << conts;
}
};
int main()
{
Test t2 = getnew(1);
cout << endl << t2.conts;
return 0;
}
Test getnew(int arg)
{
Test retj("FFFFF");
return retj;
}
Only one constructor and one destructor is called. But object t2 has value member conts initialized with correct value "FFFF". I know that return value optimizations are applied, but how object t2 is initialized?
In theory, what should happen is that the compiler creates a temporary copy of your return value and that temporary object is then assigned to the variable which receives the output of the function.
However, the compiler is allowed to elide copies and moves of a returned value even though the copy constructor or move constructor has side-effects. In your case, this turns into a so-called NRVO (Named Return Value Optimization), which is a special case of RVO (Return Value Optimization).
Thus, it is very likely that what you are seeing is a result of a move elision. There are compiler options to disable this optimization, but some compilers (e.g. Clang 3.2) have bugs handling those options (see the answer to this question).
Using return value optimization, T2 is assigned to the Test object initialized in getnew. That's how RVO works.

Understanding the life time of an object, scope, RAII

In the below code, when I pass an unnamed A variable to the ctor of B, the variable is destructed after the line. According to this answer :
Temporary objects are destroyed at the
end of the full expression they're
part of. A full expression is an
expression that isn't a sub-expression
of some other expression. Usually this
means it ends at the ; (or ) for if, while, switch etc.)denoting the end
of the statement.
I get it but how can the class B know the value of its mamber_a variable, after it is destructed? I know that copy ctor of A is enver called. How is this possible?
#include <iostream>
using namespace std;
class A
{
int sign;
A();
const A & operator=(const A &);
public:
A(int x) : sign(x) {
cout << "A ctor : " << sign << endl;
}
void WriteA() const {
cout << sign << endl;
}
~A() {
cout << "A dtor : " << sign << endl;
}
A(const A &) {
cout << "A copied : " << sign << endl;
}
};
class B
{
int sign;
const A & member_a;
public:
B(const A & aa , int ww ) : sign (ww) ,member_a(aa) {
cout << "B ctor : " << sign << endl;
}
void WriteB() const {
cout << "Value of member_a :";
member_a.WriteA();
}
~B() {
cout << "B dtor : " << sign << endl;
}
};
int main() {
A a(10);
B b1(a,1);
b1.WriteB();
B b2(A(20),2);
b2.WriteB();
return 0;
}
The output is :
A ctor : 10
B ctor : 1
Value of member_a :10
A ctor : 20
B ctor : 2
A dtor : 20
Value of member_a :20 // Object A was destructed. Where does this 20 come from?
B dtor : 2
B dtor : 1
A dtor : 10
You have one of the tricky parts of C++
It is pure chance that member_a has the value 20. You are hitting what is refereed to as undefined behavior.
When a class retains a reference to an external object it is the responsibility of the programmer to make sure that the lifetime of the object lasts longer than the object being referred to. In this case when you call member_a.WriteA(); the a object has already been destroyed and thus you are accessing memory that may potentially not belong to you (in this case it just happens to be in a location nearby that has not been overridden (completely by chance)).
If you are going to retain a reference to an object. You can retain a const reference but sometimes it is best to make the parameter a normal reference so that you can not accidentally pass a temporary value (this does not always work as you may have to pass a const object by reference).
Using a reference to a destructed object is an "undefined behaviour".
In A's destructor, try setting "sign" to "-1" and see what happens. Odds are the call to "WriteB" will show that you have sent a message to a deceased object.
Now try putting a bunch of stack using code between the constructor of b2 and the call to b2.WriteB, for example a call to a subroutine. You will probably now find that the call prints something different.