-1

Sample using "new" operator:

Object_A *A = NULL;

if (some_condition) {
  A = new Object_A();
  /*some code*/
} else {
  A = new Object_A_Child();
  /*some other code*/
}

/* some code which involves 'A' */

delete A;

Is there any way without using new and delete operator?

Because there are multiple such variables in my code, and it gets clumsy if I do it like that, whereas it remains very clean if I just use static variables inside if block. But the problem with that is, I have to move the common post-processing and repeat it in both if and else blocks!

PS: As per comments, the smart-pointers would atleast get rid of delete operator.

Ayush
  • 302
  • 2
  • 10
  • The null check is redundant, deleting a null pointer is a well-defined no-op. – StoryTeller - Unslander Monica May 08 '23 at 18:06
  • Oh, I was in otherwise impression till now. Thanks for informing. – Ayush May 08 '23 at 18:07
  • For most types it can just be `Object_A A;`, especially if `new Object_A();` is valid. Otherwise `std::optional A;`. – user17732522 May 08 '23 at 18:07
  • Is heap allocation needed? Do you know the RAII concept? – Bob__ May 08 '23 at 18:08
  • Just turn `Object_A* A = null` into `Object_A A;` and all is fine, provided `Object_A` can be default constructed – 463035818_is_not_an_ai May 08 '23 at 18:12
  • your current approach is not only clumsy, but also error prone and not exception safe. You should read about smart pointers – 463035818_is_not_an_ai May 08 '23 at 18:13
  • Hi @463035818_is_not_a_number , Sorry my question was incomplete. I edited it. Actually, I am creating a child object also in "else" block. So `Object_A A;` approach didn't work in my case. Yeah smart pointers will make code little cleaner, thanks for suggesting, I totally forgot about them -_- – Ayush May 08 '23 at 18:29
  • related/dupe: https://stackoverflow.com/questions/76102816/creating-static-unique-ptr-with-ternary-operator – NathanOliver May 08 '23 at 18:29
  • there are ways, but what is viable and applicable in your case depends on details you left out. For example what is `/*some code*/` and `/*some other code*/` ? – 463035818_is_not_an_ai May 08 '23 at 18:33
  • 1
    With the changes you would use `std::unique_ptr A;` instead. – user17732522 May 08 '23 at 19:00
  • Do you want to reserve stack space to hold the object outside the `if` block, then create the object inside the `if` block but in the reserved space and then have the object be destroyed when the reserved stack space goes out of scope? It seems a bit weird to me -- you want to create a new object inside the `if`, but you don't want to use the keyword `new` to do it? Why not? What do you want the code that you show using `new` to look like? – David Schwartz May 08 '23 at 19:02

1 Answers1

0

One option is to use std::unique_ptr instead of raw pointers. However, if you do not want to have a dynamic allocation you can also use std::variant:

std::variant<A, A_Child> a;
if (some_condition) {
  a.emplace<A>(/*arguments to A's ctor*/);
} else {
  a.emplace<A_Child>(/*arguments to A_Child's ctor*/);
}
// optionally:
A& ar = std::visit([](auto& obj)->A& {return obj;}, a);
ar.function();
// no delete necessary

This demo shows that the optimiser even sees what you're doing and completely removes the virtual indirection:

A_Child::function():
        mov     edx, 8
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        jmp     std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
main:
        sub     rsp, 24
        mov     rdi, rsp
        mov     QWORD PTR [rsp], OFFSET FLAT:vtable for A_Child+16
        mov     QWORD PTR [rsp+8], 1
        call    A_Child::function() // <------------ direct call
        xor     eax, eax
        add     rsp, 24
        ret
bitmask
  • 32,434
  • 14
  • 99
  • 159