Как сделать объект внутри функции и вернуть его в main () без деструктора, удалить его в c ++?

У меня есть этот класс:

class foo{

public:
foo();
foo(const int& var);
foo(const foo& var);
~foo();

foo retSumOf(const foo& var1, const foo& var2);

private:
int a;
char* x;

};

и эта функция meber:

foo foo::retSumOf(const foo& var1, const foo& var2){

//Make somehow a foo object,
//lets name it 'result'

result.a = var1.a + var2.a;

return (result);
}

Я хочу сделать это в основном:

main(){

foo a, b;
foo* c;

a.a = 1;
b.a = 2;

c = retSumOf(a, b);

cout << "sum =" << c->a;

}

без вызова (перегруженного) конструктора копирования!

Есть ли в C ++ способ динамически создать объект из функции и вернуть его адрес? Без конструктора, чтобы удалить его в конце вызова retSumOf ()?

1

Решение

Измените функцию следующим образом:

foo* foo::retSumOf(const foo& var1, const foo& var2){

//Make somehow a foo object,
//lets name it 'result'
foo* result = new foo();

result->a = var1.a + var2.a;

return (result);
}
3

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

Зачем?

Да, вы можете вернуть (умный) указатель, как говорит Джереми, но зачем вам это делать? Почему бы вместо этого правильно реализовать функции копирования и перемещения? У вас уже есть конструктор; по правилу пяти вы все равно должны реализовать остальные четыре функции или подавить их.

5

Во-первых, есть несколько способов:

Вы можете использовать возвращаемое значение в качестве аргумента:

void foo::computeSumOf(foo & result, const foo& var1, const foo& var2) ...

Другой способ заключается в том, чтобы воспользоваться Оптимизация RVO

foo foo::retSumOf(const foo& var1, const foo& var2)
{
return foo(var1.a + var2.a);
}
//...
foo x = someFoo.retuSomOf(a,b);

В-третьих (если вы можете использовать c ++ 11), вы можете использовать конструктор перемещения и записи, чтобы избежать конструктора копирования. Делая это, вы можете оптимизировать ненужную копию членов и просто «переместить» память из одного экземпляра в другой. Вы можете найти больше информации Вот.

class foo{
public:
foo(foo && rValue) { ... };
foo& operator = (foo && rValue) { ... };
...
};
foo foo::retSumOf(const foo& var1, const foo& var2){
foo result;
//same code
return result;
}

Наконец, вы можете использовать shared_ptr или другие умные указатели (например, intrusive_ptr)

std::shared_ptr<foo> foo::retSumOf(const foo& var1, const foo& var2){
std::shared_ptr<foo> result = new foo;
result->a = ...
return result;
}
3

Вы можете объявить его как статический:

static myClass objName;

или используйте новое (предпочтительно):

myClass* objName = new myClass;
return objName

Если вы используете второй метод, вам нужно изменить функцию, чтобы она возвращала указатель, а не объект.

1

Вы можете вернуть значение из функции в качестве ссылки на foo и сохранить его в const foo&, Const-ссылка продлит срок службы foo экземпляр на срок службы переменной.

foo& foo::retSumOf(const foo& var1, const foo& var2)
...
const foo& c = retSumOf(a, b);

РЕДАКТИРОВАТЬ

Оказывается, это не работает: http://ideone.com/WM3bIe

0

Просто сделай это

class foo
{
...
friend foo retSumOf(const foo& var1, const foo& var2);
...
};

foo retSumOf(const foo& var1, const foo& var2);
{
foo result;
result.a = var1.a + var2.a;

return (result);
}

а также включить оптимизацию компилятора.
Поскольку в вашей функции есть только один оператор возврата, и result локально, компилятор создаст его в стеке вместо возвращаемого значения, избегая копирования.

Не нужно беспокоиться об этом. (и да, не нужно называть «переезд»).

Если вы хотите более «функциональный» подход, дайте foo конструктор, который определяет значения членов и использует accordngly:

class foo
{
// you existing code andd ...

foo(int i, const char* s) :a(i), x(s)
{}
};

так что вы можете сделать

foo retSumOf(const foo& var1, const foo& var2)
{  return foo(var1.a + var1.b, nullptr); }

Это даже имеет смысл, вы можете назвать retSumOf просто operator+ и имеют c = a+b;

В любом случае, избегайте c как голый указатель: никогда не будет ясно, кто должен удалить полученный объект. Это должно быть только значение.

Никогда не используйте char * в качестве участника: неясно, кому принадлежат данные после назначения или копии. использование std::string вместо.

0

Не уверен, что мой ответ правильный, но на самом деле он все время работает для меня:

#include <iostream>

class Foo
{
public:
Foo() {std::cout<<"HEY!";}
~Foo() {}
};Foo&& GetFoo()
{
return std::move(Foo());
}int main()
{
GetFoo();
return 0;
}

Обычно я просто перемещаю объект, созданный внутри функции. Просто, чтобы я мог как можно больше избегать указателей. В противном случае я бы использовал указатель Smart, но вышеизложенное — то, что я обычно делаю.

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector