Возврат объекта из функции Stack Overflow

Допустим, у меня есть переменная, которая указывает на объект, который я сделал. В этом примере, скажем, у меня есть объект, который представляет карту, которая имеет 2 члена — ранг и масть.

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

Мой вопрос заключается в том, что если я хочу функцию, которая возвращает этот объект карты, который я создал:
Я хочу сделать что-то вроде этого:

Card* playerCard = foo()

Я знаю, что playerCard указывает на объект карты, так значит ли это, что foo () также должна возвращать объект карты? Есть ли другой подход к этой проблеме?

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

Спасибо за помощь!

-1

Решение

Я собираюсь постепенно переходить от плохих к хорошим методам.

Во-первых, это неправильный способ сделать это:

Card* foo() {
Card c;
return &c;
}

Определенно не делай этого. Card c будет уничтожен в конце foo и поэтому возвращаемый вами указатель будет указывать на недопустимый объект.

Вы мог сделай это:

Card* foo() {
return new Card();
}

Карта, созданная new Card() имеет динамическое время хранения, поэтому оно не уничтожается в конце foo, Поэтому возвращенный указатель все еще указывает на эту карту. Затем вы можете использовать указатель и быть в безопасности.

Однако у этого есть еще один недостаток. Не понятно человеку, который звонит foo, но теперь они ответственны за delete на указатель, который был возвращен, чтобы убедиться, что нет утечек памяти. Вместо этого лучше всего использовать умный указатель, чтобы четко передать право владения вызывающей стороне:

std::unique_ptr<Card> foo() {
return std::unique_ptr<Card>(new Card());
}

Однако еще лучше, если вам вообще не нужно динамическое распределение. Почему бы просто не вернуть Card и пусть это будет скопировано из функции? Вы можете сделать это так:

Card foo() {
return Card();
}

Тогда вместо присвоения указателю вы бы вызвали функцию следующим образом:

Card c = foo();

Это, конечно, зависит от ваших требований, позволяющих это. Если вы хотите использовать Card* полиморфно, вам нужно использовать один из подходов указателя. В противном случае вы в конечном итоге нарезать Card производные.

7

Другие решения

Вы возвращаете указатель на объект, а не объект.

Я точно не знаю, в чем ваша проблема, поэтому приведу полный пример:

struct card {int rank; int suit};

card make_a_card() {
return card{10,3};
}

int main() {
card a_card = make_a_card();
// a_card == card{10,3}
}

Вы редко хотите возвращать необработанные указатели из функции. Это не нужно для скорости (на самом деле, благодаря RVO и семантике перемещения это может на самом деле оказаться медленнее), поэтому кроме полиморфизма времени выполнения (то есть для фабричного метода) нет особых причин делать это.

1

Если функция foo () возвращает указатель на объект Card, который уже создан, назначение указателя Card на него должно работать нормально. Важно помнить, что вы эффективно передаете его та же карта хотя, не копия или что-нибудь.

0

Вы можете использовать динамическое выделение памяти, если хотите вернуть указатель, иначе ваш указатель не будет указывать ни на что после выполнения foo (увидеть Висячие указатели):

Card* foo() {
Card* ret = new Card(...);
...
return ret;
}

Другая версия приведенного выше кода будет использовать std::unique_ptr из стандартной библиотеки, чтобы дать понять программисту клиента вашего кода, что вы возвращаете динамически выделенный указатель. Это умный указатель, поэтому он автоматически освобождает себя в конце своей области видимости (что не в конце функции, потому что он копируется в вызывающий блок).

В противном случае, если ваш объект / структура не дорогой для копирования, вы можете вернуть его по значению, ведущему к созданию копии:

Card foo() {
Card ret(...);
...
return ret;
}
0
По вопросам рекламы [email protected]