Как сохранить строку в строку * член класса в C ++? - PullRequest
4 голосов
/ 20 марта 2020

У меня есть класс C ++, который содержит в своих членах std::string*. Я хочу сделать конструктор для этого класса, который принимает std::string в качестве аргумента и заставляет указатель строки указать на него:

class foo
{
private:
    std::string * bar;
public:
    foo(std::string);
}
foo::foo(std::string s)
{
    //code
}

Если я делаю this->bar = &s;, это, очевидно, не работает (сохраняет адрес строки s, как и положено). Как мне go сделать это?

Я попытался создать конструктор, который принимает указатель строки в качестве аргумента, но он также не работал должным образом, я полагаю по аналогичным причинам.

Изменить: После прочтения комментариев я решил изменить конструктор, так что теперь он принимает std::string* в качестве аргумента и работать оттуда вперед.

Ответы [ 2 ]

6 голосов
/ 20 марта 2020

Вы можете написать свой конструктор следующим образом:

foo::foo(std::string s)
{
    bar = new std::string(s);  // code
}

Но теперь у вас есть утечка памяти, поэтому вам нужен деструктор:

foo::~foo() { delete bar; }

А затем вам нужно реализовать или отключить копирование / назначение.

class foo final
{
   ...
   foo(const foo&) = delete;
   foo& operator=(const foo&) = delete;
   ...
 };

Это все, что нужно для сохранения указателя на std::string вместо экземпляра:

class foo final
{
    std::string bar;  // NOT std::string* bar
public:
    foo(std::string s) : bar(s) {}
};

Если вы действительно хотите указатель, он было бы намного лучше использовать std::unique_ptr или std::shared_ptr.

class foo final
{
    std::unique_ptr<std::string> bar;
public:
    foo(std::string s) : bar(std::make_unique<std::string>(s)) {}
};

std::unique_ptr нельзя скопировать / назначить, поэтому вам даже не нужно отключать Копирование / назначение для foo, хотя вы можете захотеть для лучшего сообщения об ошибках.

0 голосов
/ 20 марта 2020

Если абсолютно необходимо иметь указатель на строку - убедитесь, что приобрели право собственности на эту строку (например, сначала сделав внутреннюю копию). Чем инициализировать ваш указатель с адресом этой копии.

class foo
{
private:
    std::string * bar;
    std::string redundantCopyOfTheString;
public:
    foo(std::string);
}
foo::foo(std::string s):
   redundantCopyOfTheString(s),
   bar(&redundantCopyOfTheString)
{
    //code
}

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

Я предлагаю вам описать проблему, которая привела вас к этому решению на основе указателей, и опубликовать в виде отдельного вопроса с просьбой улучшить дизайн.

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