0

I wrote a class in Visual Studio 2017:

class Person
{
public:
    Person() {cout << "construtor" << endl; };
    Person(istream&a);
    Person(const Person&a) :name(a.name), address(a.address) { cout << "copy construtor" << endl; }
    ~Person() { cout << "destructor" << endl; };
private:
    string name;
    string address;
}
Person::Person(istream&a)
{
    a >> name >> address;
    cout << "call fuction" << endl;
}
int main()
{
    Person a =Person(cin);
    return 0;
}

In my opinions,I think Person(cin) may create a temporary obeject;It call FunctionsPerson(istream&a);Then was acreated by copy construtor. So I think the debug results should be like this if I enter Jack CN:

Jack CN
call fuction
copy constructor
destructor
destructor

But the result is amazing actually:

Jack CN
call fuction
destructor

I have seen that copy initialization happens in using =to define variable in C++ primer.Why it didn't happen here.I am searching for a long time on net. Someone talked to me that Person a =Person(cin); equals Person a(cin) here;When I debugged,they got the same results.

But I thought of a method.I tried to put Person(const Person&a) :name(a.name), address(a.address) { cout << "copy construtor" << endl; } into private:. An amazing things happended.The version of Person a(cin) successfully compiled and run.The version of Person a =Person(cin);didn't compile;Person::Person(const Person&a) is Inaccessible.So if Person a =Person(cin); equals Person a(cin) here.Why Person a =Person(cin);can not be compiled.And if Person a =Person(cin); did not call copy construtor.Why when I put it into private: ,it went wrong.So I want to know how ain Person a =Person(cin) is initializated.

Is there some compiler optimization or my opinion is wrong? I am searching for a long time. But no use. Please help or try to give some ideas how to achieve this. Thanks in advance.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • If you use a compiler that is a bit more recent, you'll see that even if the copy constructor is private, [it compiles](https://godbolt.org/g/xcq3vU). :) – Rakete1111 Mar 24 '18 at 06:11
  • thank you for your answer sincerely – Miralan Mar 24 '18 at 06:17
  • @user9127904 -- *In my opinions,I think Person(cin) may create ...* -- You even say it yourself. You used the word "may", implying that things may be done that way, and maybe not. It all depends on the compiler and compiler optimizations. – PaulMcKenzie Mar 24 '18 at 06:22
  • @Rakete1111 [cppref](http://en.cppreference.com/w/cpp/language/copy_elision) says "When a nameless temporary, not bound to any references,would be copied or moved (since C++11) into an object of the same type",the copy constructor still must be present and **accessible**.So using **private** is ill-formed. – choxsword Mar 24 '18 at 06:33
  • 1
    @bigxiao Jup, that's why I mentioned *newer* compilers :) Well anyways, look at the first paragraph in cppref you quoted. In C++17, prvalues do not create objects, they are just "recipes" that in some cases create objects. That's why it works. – Rakete1111 Mar 24 '18 at 06:36
  • @PaulMcKenzie Why does the return value of function still requires **accessible** in c++17? As far as I know,the return value is also prvalue. – choxsword Mar 24 '18 at 06:52
  • @PaulMcKenzie c++17 says "If return expression is a prvalue, the object returned by the function is initialized directly by that expression. This does not involve a copy or move constructor when the types match ",what does that mean? Why does it use the term "object"? in c++17 prvalue is not a object any more. – choxsword Mar 24 '18 at 06:59

0 Answers0