C ++ ссылка в конструкторе - PullRequest
       9

C ++ ссылка в конструкторе

2 голосов
/ 10 сентября 2009

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

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

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 (), что происходит с моей ссылкой на него внутри экземпляра класса? Я думаю, что это становится недействительным. Будет ли лучше держать копию в классе? Я просто хочу избежать ненужного копирования потенциально больших объектов, таких как строка ...

Ответы [ 7 ]

8 голосов
/ 10 сентября 2009

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

3 голосов
/ 10 сентября 2009

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

1 голос
/ 10 сентября 2009

Да, std :: string исчезнет, ​​но c str "hello" не будет, поскольку является константой.

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

1 голос
/ 10 сентября 2009

Вам не нужно делать копирование. Объявите член 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");
}
1 голос
/ 10 сентября 2009

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

0 голосов
/ 10 сентября 2009

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

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

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

0 голосов
/ 10 сентября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...