Following program is giving the output as expected
#include <iostream>
#include <string>
using namespace std;
class test
{
string name; // non-referance
public:
test(string name1 = "default") :name (name1) { cout << name << " is constructed"<< endl;}
~test() { cout << name << " is destructed"<<endl;}
};
int main()
{
test t1("Mike");
test t2;
}
OUTPUT: As expected
Mike is constructed
default is constructed
default is destructed
Mike is destructed
When data member "name " is changed into reference variable, output is different( when both object are destructed, " name" values ("Mike" and "default") from output is gone , why?
class test
{
string &name; // **Make it reference**
public:
test(string name1 = "default") :name (name1) { cout << name << " is constructed"<< endl;}
~test() { cout << name << " is destructed"<<endl;}
};
OUTPUT: "Mike" and "default" are missing
Mike is constructed
default is constructed
is destructed
is destrcuted
答案 0 :(得分:4)
The name1
parameter is local to the test
constructor. It goes out of scope and is destroyed when the test
constructor exits.
When name
is not declared to be a reference, it is an actual string
object whose lifetime is that of its containing test
object. It copies data from name1
when initialized. As such, when name
is used later in the test
destructor, it is still a valid object with its own data, and you see the output you are expecting.
When name
is declared to be a reference instead, it is not an object of its own, it is bound to the name1
object (it becomes an alias for name1
), and is thus left dangling when name1
is destroyed. As such, when name
is used later in the test
destructor, it is no longer referring to a valid string
object, and the code has undefined behavior.
The only way to make the latter case work correctly is to have name1
also be a reference to some external string
that remains valid for the lifetime of the test
object, eg:
#include <iostream>
#include <string>
using namespace std;
class test
{
string &name;
public:
test(string &name1) :name (name1) { cout << name << " is constructed" << endl; }
~test() { cout << name << " is destructed" << endl; }
};
int main()
{
string name1 = "Mike";
test t1(name1);
string name2 = "default";
test t2(name2);
}