473,325 Members | 2,870 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Storing objects in a vector

I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
2). Why is the destructor called after mc has been pushed into the vector?
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al
Jul 23 '05 #1
12 3894
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor, i.e., the number of calls to the first two
must balance with the destructor calls.


I have the the following questions:

1). Why is the copy constructor called TWICE? Not if I compile and run your program.
2). Why is the destructor called after mc has been pushed into the vector? Because push_back creates a copy.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope? The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :
Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al


Jul 23 '05 #2


Stephan Brönnimann wrote:
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !

Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,


What does that mean in plain English ?

i.e., the number of calls to the first two must balance with the destructor calls.

Huh?

I have the the following questions:

1). Why is the copy constructor called TWICE?
Not if I compile and run your program.


Hmm ....

2). Why is the destructor called after mc has been pushed into the vector?
Because push_back creates a copy.


I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.

3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?


The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.
i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al



Jul 23 '05 #3
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal()
<< endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " <<
mv[0].getVal() << endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
Not sure. My implentation seems to make a temporary local copy, before copying it to where it will end up.
2). Why is the destructor called after mc has been pushed into the vector?
The temporary copy goes out of scope.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
Yes.
(ii) clear() is invoked
Should be equivelant to:
vec.erase(vec.begin(), vec.end())
(iii) vector goes out of scope?
Yes.

But remember that if you use pointers to your objects, it is the pointers it both copies AND deletes, not the objects they point to.
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?


The fact that copying probably isn't as expensive as you think, and that you shouldn't prematurely optimise.

You could use a reference counted pointer to store your objects if they really are that expensive to copy. Look at boost smart pointers:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

Benchmark both approaches, but don't forget that something like a reference counted pointer introduces overhead too (counting when you copy, and indirection when you access)

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #4
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,

What does that mean in plain English ?


It means he didn;t read the bit that said you hadn't completed the program.
i.e., the number of calls to the first two
must balance with the destructor calls.


Huh?


In total, you should have 1 construction, 2 copies and 3 destructions.
I have the the following questions:

1). Why is the copy constructor called TWICE?

Not if I compile and run your program.

Hmm ....


I get two copies when compiled and run.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #5


Ben Pope wrote:
Alfonso Morra wrote:


Stephan Brönnimann wrote:

>> Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,


What does that mean in plain English ?

It means he didn;t read the bit that said you hadn't completed the program.
i.e., the number of calls to the first two
must balance with the destructor calls.


Huh?

In total, you should have 1 construction, 2 copies and 3 destructions.
I have the the following questions:

1). Why is the copy constructor called TWICE?

Not if I compile and run your program.


Hmm ....

I get two copies when compiled and run.

Ben


Thanks for the clarification Ben. Your previous post was veery useful
also - atleast I know I'm not going mad (w.r.t to the copy constructor
being called twice :-) )

Jul 23 '05 #6


Alfonso Morra wrote:
Stephan Brönnimann wrote:
2). Why is the destructor called after mc has been pushed into the vector?
Because push_back creates a copy.


I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.


Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?


The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)


I your special case I agree, but that is because of ~MyClass()
and not because of the vector. Consider: what should happen
for std::vector<int>?

Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.


std::vector manages its own allocated memory, that's it.
The memory management of the vector's content is up to you.

regards, Stephan

Jul 23 '05 #7


Stephan Brönnimann wrote:

Alfonso Morra wrote:
Stephan Brönnimann wrote:

2). Why is the destructor called after mc has been pushed into the vector?

Because push_back creates a copy.
I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.

Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)

3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?

The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)

I your special case I agree, but that is because of ~MyClass()
and not because of the vector. Consider: what should happen
for std::vector<int>?

Please see my comment below
Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.


This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.

std::vector manages its own allocated memory, that's it.
The memory management of the vector's content is up to you.

regards, Stephan


Jul 23 '05 #8
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Alfonso Morra wrote:
Stephan Brönnimann wrote:
> 2). Why is the destructor called after mc has been pushed into the
> vector?

Because push_back creates a copy.

I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.


Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)


I'm not sure what you think is syntactic suger. When you request for the copntainer to remove the element, the container will call the destructor of that item, and then remove
that item from the container and then deallocate any memory required to store that item. If that item is a pointer, and you allocated memory at the end of that pointer, thats
still your responsibility.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #9


Ben Pope wrote:
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Alfonso Morra wrote:

Stephan Brönnimann wrote:
>> 2). Why is the destructor called after mc has been pushed into the
>> vector?
>
>
> Because push_back creates a copy.
I dont understand the point you're making, creating a copy of a
variable
is not the same as deleting the variable - in other words, the fact
that
a copy is made of variable mc does not explain why it is fred.
Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)

I'm not sure what you think is syntactic suger. When you request for
the copntainer to remove the element, the container will call the
destructor of that item, and then remove that item from the container
and then deallocate any memory required to store that item. If that
item is a pointer, and you allocated memory at the end of that pointer,
thats still your responsibility.

Ben


Thats not what I meant, (the term syntactic sugar being overloaded in
this particular usage) I was just being lazy and meant to say, the
phrases "deleting an object", "an objects destructor is called" are in
most cases, (certainly in this case) equivalent, and is largely a matter
of "syntax" (not in the computer language terminolgy sense).

Jul 23 '05 #10
In your case which deals with std::vector<MyClass>
calling ~MyClass() and to delete an allocated object of MyClass
is exactly not the same!

Just to prevent your next missunderstanding:
If you delete a pointer to an object the destructor of that object is
called.

Stephan

Jul 23 '05 #11


Stephan Brönnimann wrote:
In your case which deals with std::vector<MyClass>
calling ~MyClass() and to delete an allocated object of MyClass
is exactly not the same!

Just to prevent your next missunderstanding:
If you delete a pointer to an object the destructor of that object is
called.
This is exactly what I'm saying ...
Stephan


Jul 23 '05 #12
Alfonso Morra wrote:

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;
mv.push_back(mc) ;
}

Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !

I have the the following questions:

1). Why is the copy constructor called TWICE?
2). Why is the destructor called after mc has been pushed into the vector?
One possibility is if your compiler's "push_back" function is
declared as taking an object by value (rather than by reference).
Then the extra creating and destruction is this local variable
in the push_back() function. You could confirm this by examining
your compiler's header files.

I can't think of any good reason why push_back would be declared
as taking the parameter by value though (mine takes it by reference),
and I don't know if this should be considered a compiler bug or not.
ISTR that compilers are allowed to make extra copies of objects
whenever they feel the need.
instead in the vector?. Storing copies rather than the original items
in a vector seems quite an inefficient/expensive way of going about
things i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption
You don't need to delete the original object right away.
In your example you could use 'mc' for other things (eg. fill
out more data to it and push_back() it again).
It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...


So why do you declare a temporary object and delete it a moment
later, in your assignment operator? :)

Jul 23 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: mjkahn | last post by:
I've read (and read!) that you shouldn't store objects in Session variables. I've read these reasons: - The object takes up memory that may not be freed until the session times out. Better to...
6
by: Alfonso Morra | last post by:
I have written the following code, to test the concept of storing objects in a vector. I encounter two run time errors: 1). myClass gets destructed when pushed onto the vector 2). Prog throws a...
4
by: Frank Rizzo | last post by:
In classic ASP, it was considered a bad idea to store VB6-created objects in the Application variable for various threading issues. What's the current wisdom on storing objects in the Application...
9
by: david | last post by:
I have a class with some business-logic and with every roundtrip, I need an instance of this class, so I have to create it, every time again. That doesn't seem very efficient. I thought it would...
1
by: Miesha.James | last post by:
Hello, I'm trying to rewrite visual c++ code into visual c++ .NET code and I've run across a problem with storing objects into a list. Here;s an example of the code I have: ref struct...
13
by: r.z. | last post by:
I logged construtor and destructor calls for one of my classes and I discovered that the constructor was called only once while the destructor was called 3 times for a single object. I have a...
3
by: Bruno.DiStefano | last post by:
Hi All, BACKGROUND INFO I need to use a "vector" structure to store a number of objects that becomes known only at run time. The constructor, at instantiation time of a new object, increments a...
4
by: alexjcollins | last post by:
The following program demonstrates the problem: #include <vector> #include <iostream> #include <tvmet/Vector.h> typedef tvmet::Vector<double, 3Vector3d; class Mesh {
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.