Domanda

I have a class that has a private string pointer. This class also has a public method that dereferences that string pointer and returns the resultant string to the caller. My question is this: what happens to the memory that holds the dereferenced string?

Here's my code:

#include <iostream>
#include <string>

class myclass
{
    private:
        std::string *_name;

    public:
        myclass()
        {
            this->_name = new std::string("my name");
        }

        ~myclass()
        {
            delete this->_name;
        }

        std::string getName()
        {
            return *this->_name;
        }
};

void main()
{
    myclass m;
    {
        std::string str = m.getName(); //what happens to this memory?
        std::cout << str << std::endl;
    } //str deleted here (I think)
    //here, the m._name pointer hasn't yet been deleted
}

In my main function, the variable str gets assigned the dereferenced string. What happens to the memory that holds this string? I think that the memory is held on the stack and therefore gets "de-allocated" automatically when the variable goes out of scope. What confuses me is that the private string pointer may still be in scope even if the dereferenced string is no longer in scope. Does the str variable get assigned a copy of the private _name pointer's value?

If this code does copy the string in the background, should I be concerned about performance. Would my code run faster if I simply have getName() return the _name pointer without dereferencing it?

È stato utile?

Soluzione

First off, you don't need a pointer. Second, you can return a copy (like you do) or a reference (or pointer if you want to stick with that), but there are pros and cons to either approach:

class myclass
{
private:
    std::string _name;
public:
    myclass() : _name("my name")
    {
    }
    std::string getName1() { return _name; }
    std::string& getName2() { return _name; }
    const std::string& getName3() const { return _name; }
}

getName1 returns by value. The con is that a copy gets made, which can impact performance, but the returned value is safe to use after the object goes out of scope.

The difference between getName2 and getName3 is that you can use the former to modify the actual member of the class. The con is that the reference can no longer be used if the object goes out of scope, so you'd be left with a dangling reference. The pro is that it's more efficient, since there's no copying involved.

myclass x;
std::string a = x.getName1(); // copy is made
std::string& b = x.getName2(); // no copy
                               // b is mutable
b = "something else";  //this will modify x._name
const std::string& c = x.getName3; // no copy
                                   // c is const

myclass* y = new myclass;
std::string d = x.getName1();  // copy is made
std::string& e = x.getName2(); // no copy
delete y;
d = "something else"; //legal
e = "something else"; //undefined behavior, e is a dangling reference

Altri suggerimenti

Follow the "rule of three". If you define any of: copy constructor, assignment operator, destructor, then define all of them. Then there will be no confusion whether the pointer to the string was deleted: you would just have a new one created in the corresponding assignment operator.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top