Вопрос

У меня есть класс, конструктор которого принимает постоянную ссылку на строку.Эта строка действует как имя объекта и, следовательно, необходима на протяжении всего срока службы экземпляра класса.

Теперь представьте, как можно было бы использовать этот класс:

class myclass {
public:
    myclass(const std::string& _name) : name(_name) {}
private:
    std::string name;
};

myclass* proc() {
    std::string str("hello");
    myclass* instance = new myclass(str);
    //...
    return instance;
}

int main() {
    myclass* inst = proc();
    //...
    delete inst;
    return 0;
}

Поскольку строка в proc() создается в стеке и, следовательно, удаляется по завершении работы proc(), что происходит с моей ссылкой на нее внутри экземпляра класса?Я предполагаю, что это становится недействительным.Было бы лучше, если бы я сохранил копию внутри класса?Я просто хочу избежать любого ненужного копирования потенциально больших объектов, таких как строка...

Это было полезно?

Решение

Да, ссылка становится недействительной в вашем случае. Поскольку вы используете строку, лучше сохранить копию строкового объекта в классе myclass .

Другие советы

Во что бы то ни стало: скопируйте. Иметь " std :: string name " член в вашем классе. Это единственный способ контролировать время жизни.

Если myclass :: _ name не является ссылкой, оно копируется и не становится недействительным.

Вам не нужно делать копирование. Объявите элемент std :: string name (не ссылочный) в myclass (который вы как-то вообще пропустили). и передайте const char * в качестве аргумента. Таким образом, вы создадите свой объект name прямо в классе без копирования.

class myclass {
public:
    std::string name;
    myclass(const char *_name) : name(_name) { }
};

myclass *proc() {
    return new myclass("hello");
}

Да, std::string исчезнет, но c str "hello" не исчезнет, поскольку это константа.

У вас есть два возможных ответа.Используйте c str в качестве ссылки или сделайте std:string staic.

Поле myclass :: name должно иметь тип std :: string. Строки в C ++ копируются при записи ( http://en.wikipedia.org/ wiki / Copy-on-write ), чтобы у вас не возникало проблем с копированием больших объектов.

Сохраняйте копию строки в MyClass, сохраняя ссылку, безусловно, не безопасно. Если вы ожидаете, что многие экземпляры будут иметь одно и то же имя, вам следует изучить шаблон дизайна Flyweight который позволяет экономить память, когда у вас много одинаковых экземпляров. Boost.Flyweight - очень удобная реализация этого шаблона, который позволяет просто написать:

class myclass {
public:
    myclass(const std::string& _name) : name(_name) {}
private:
    boost::flyweight<std::string> name;
};

Некоторые реализации std :: string могут делать это за сценой, но это не обязательно. Поэтому не стоит полагаться на это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top