how to return object without create copy of that?

一世执手 提交于 2019-12-11 14:35:10

问题


I develop simple c++ class to testing when c++ objects destroy; now I have a problem, when an object return by function, c++ create a new object and return that and when return reference destroy object what is my mistake ?

simple class attached below.

#include <iostream>

using namespace std;

static int freeCounter=0;

class TestCopy {
private:
    string pStr;
public:
    TestCopy(const TestCopy &obj){
        pStr=obj.pStr;
    }
    TestCopy(string &test){
        pStr=test;
    }
    ~TestCopy(){ freeCounter++; cout << freeCounter <<"\t" << pStr << endl; }

    TestCopy get(){
        TestCopy x=*this; 
        return TestCopy(x); // -> TestCopy(x) is first destroy in result
    }

    string getStr(){
        return pStr;
    }
};

int main(){
    string xstr="test";
    TestCopy x(xstr); // x is third destroy
    TestCopy x2=x.get(); // x2 is second destroy

    cout << x.getStr() << endl;

    return 0;
}

and result

1   test
test
2   test
3   test

回答1:


x in function get is a local object, when the function finishes, x will be destroyed.

so, x is the first destroyed.




回答2:


First a review of OP's code. I've modified it slightly to make what's going on more obvious.

#include <iostream>

using namespace std;

static int allocCounter = 0;

class TestCopy
{
private:
    string pStr;
    int counter;
public:
    TestCopy(const TestCopy &obj)
    {
        allocCounter++;
        counter = allocCounter;
        cout << "copy construct " << counter << endl;
        pStr = obj.pStr;
    }
    TestCopy(const string &test)
    {
        allocCounter++;
        counter = allocCounter;
        cout << "string construct " << counter << endl;
        pStr = test;
    }
    ~TestCopy()
    {
        cout << counter << "\t" << pStr << endl;
    }

    TestCopy get()
    {
        TestCopy x = *this; // copy constructed
        return TestCopy(x); // copy constructed and copy elision
    }

    string getStr()
    {
        return pStr;
    }
    TestCopy & operator=(const TestCopy &obj)
    {
        cout << "assigned " << obj.counter << " to "<< counter << endl;

        pStr = obj.pStr;
//        counter = obj.counter; deliberately left out
        return *this;
    }

};

int main()
{
    string xstr = "test";
    TestCopy x(xstr); // string constructed
    TestCopy x2 = x.get(); // Would be a copy constructed if not for copy elision
    return 0;
}

Output

string construct 1
copy construct 2
copy construct 3
2   test
3   test
1   test

Note no calls to the assignment operator even with TestCopy x=*this;

Alright. Now how do we chop some of this down?

First we get rid of a redundant copy in get

TestCopy get()
{
    return *this; // copy constructed. Or is it? The copy construction could
                  // happen at the caller. Either way it is copied and elided
}

Output

string construct 1
copy construct 2
2   test
1   test

So at this point we know there is no need to copy or assign in get because the return statement will do it for us. This is the important part with respect to OP's question.

But if we change main a bit and add an assignment operator we can observe a bit more interesting behaviour.

int main()
{
    string xstr = "test";
    TestCopy x(xstr); // string constructed
    TestCopy x2(""); //string constructed
    x2 = x.get(); // assigned and a copy construct when returning from get
    cout << "done main" << endl;
    return 0;
}

Output

string construct 1
string construct 2
copy construct 3
assigned 3 to 2
3   test
done main
2   test
1   test

The return from get was assigned to x2, then destroyed. x2 gets destroyed and finally x.




回答3:


thank you @seaman with your help I found my mistake. by changing

TestCopy x=*this;

with

const TestCopy &x=*this;

problem solved



来源:https://stackoverflow.com/questions/34282543/how-to-return-object-without-create-copy-of-that

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!