Rule of three example and some questions

U

utab

Dear all,

I made a simple example case to experiment with the rule of three. The
code is below:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Exmpl{
public:
//default constructor
Exmpl(){std::cout << "Default constructor of Exmpl" << std::endl; }
// copy constructor
Exmpl(const Exmpl &);
// assignment operator
Exmpl & operator=(const Exmpl&);
// constructor with parameters
Exmpl(std::string &str,int a, double b);
// destructor
~Exmpl()
{
std::cout << "Destructor for class is used" << std::endl;
}
// getter function for the class variables
void getVals();
private:
std::string *pstring;
int i;
double d;
};

Exmpl::Exmpl(const Exmpl& NN)
{
i=NN.i;
d=NN.d;
pstring=NN.pstring;
std::cout << "Copy constructor is called" << std::endl;
}

Exmpl & Exmpl::eek:perator=(const Exmpl& NN)
{
pstring=NN.pstring;
i=NN.i;
d=NN.d;
std::cout << "Assignment operator is used" << std::endl;
}

Exmpl::Exmpl(std::string &str, int dec, double doub)
{
i=dec;
d=doub;
pstring=&str;
std::cout << "Constructor with parameters is used" << std::endl;
}

void Exmpl::getVals(){

cout << i << '\n'
<< d << '\n'
<< *pstring << '\n';
}

int main(){
string str("try example");
vector<Exmpl> vectorExmpl(5);
Exmpl a(str,0,4.5);
Exmpl b(a);
Exmpl c=b;
b.getVals();
c.getVals();
Exmpl *ptrExmpl=new Exmpl(c);
(*ptrExmpl).getVals();
delete ptrExmpl;
return 0;
}

The output of the compiled code with g++ on debian etch is:

Default constructor of Exmpl **
Copy constructor is called
Copy constructor is called
Copy constructor is called
Copy constructor is called
Copy constructor is called
Destructor for class is used **
Constructor with parameters is used
Copy constructor is called
Copy constructor is called **
0
4.5
try example
0
4.5
try example
Copy constructor is called
0
4.5
try example
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used
Destructor for class is used

My questions are on the two starred lines,

+ If I do not use a default constructor I am getting a compile time
error
+ Why is my assignment operator not working.
+ Why the destructor of the class is run in the middle, is that run
for the vector, if yes, is not vector still in the scope?

Many thanks for the replies and best regards,
 
J

Joe Greer

My questions are on the two starred lines,

+ If I do not use a default constructor I am getting a compile time
error

std::vector initializes using the default constructor. In this case, it apparently
creates one default initialized object and copies it 5 times to initialize all 5
cells of the vector.
+ Why is my assignment operator not working.

You don't have any assignments in your code. You only have initializers. These
just use the copy constructor. To get the assignment operator you need something
like:

Exmpl c;
c = a;
+ Why the destructor of the class is run in the middle, is that run
for the vector, if yes, is not vector still in the scope?

That is the destructor for the default constructed object it uses to copy construct
all the cells of the vector.
Many thanks for the replies and best regards,

HTH,
joe
 
U

utab

@v67g2000hse.googlegroups.com:





std::vector initializes using the default constructor. In this case, it apparently
creates one default initialized object and copies it 5 times to initialize all 5
cells of the vector.


You don't have any assignments in your code. You only have initializers. These
just use the copy constructor. To get the assignment operator you need something
like:

Exmpl c;
c = a;


That is the destructor for the default constructed object it uses to copy construct
all the cells of the vector.




HTH,
joe

Thanks for the clarification. The last one was the most probable to
miss :) at least by me.

Rgds,
 
A

Andrey Tarasevich

Joe said:
std::vector initializes using the default constructor. In this case, it apparently
creates one default initialized object and copies it 5 times to initialize all 5
cells of the vector.
...

Well, strictly speaking 'std::vector' doesn't use the element's default
constructor anywhere internally. The element type is not required to
have the default constructor at all. The only places when the element's
default constructors might appear is the default arguments for some
member function of 'std::vector'. Yet, once again, 'std::vector' never
relies on these default arguments internally.

This means that it's always up to the user whether to use these default
arguments (and, consequently, the default constructor of the element
type) or not. In OP's case the default argument is used in the
initialization of 'std::vector<Exmpl> vectorExmpl(5)', which is really
just a shorthand for 'std::vector vectorExmpl(5, Exmpl(),
std::allocator<Exmpl>())', taking into account the default arguments.

So, it is not exactly correct to say that "std::vector initializes using
the default constructor". 'std::vector' always initializes its elements
by using the copy constructor. It is really the user who's [implicitly]
causing the default initialization for the filler element in this case.
 
R

Ron Natalie

Joe said:
std::vector initializes using the default constructor. In this case, it apparently
creates one default initialized object and copies it 5 times to initialize all 5
cells of the vector.

It has no choice to do this. Vector's constructor as well as resize
take a single instance of the contained object to "fill" the cells
of the array. It just happens to have a default value of a default
constructed object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top