-3

I have an if-condition and I create an object inside it:

void foo() {
    Student a();
    if ( 2 < 3 ) {
       Student p();
    }
}

I don't know why but this p object is being destructed after the if-condition is finished. How can I keep this p object? Thanks in advance

I want to make the scope of this p object the same as the a object, meaning it should not be destructed till the foo() function ends. Is there a way to declare it outside the if and then initalize it inside the if ?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373

1 Answers1

-1

Whenever you enter a scope, a stackframe is 'created'. Everything you allocate to this local stack will be destroyed (the destructors of all local stack objects is called, in reverse order of creation) when you exit the scope. If you write your example like this, it becomes more obvious:

if (2 < 3)
{
    Student p;
} // scope exit, p's destructor is called

If you want to create some unknown quantity of objects, you should use a container.

#include <vector>
std::vector<Student> students;
if (2 < 3)
{
    Student p;
    students.push_back(p);
}
// use students instead of p

Edit in response to comments:

Without using containers

#include <iostream>
#include <string>
class Student
{
public:
    std::string lastname, firstname;
};

int main()
{
    Student p; // p is default initialized with empty strings
    if (2 < 3)
    {
        p = Student{"Lastname", "Firstname"}; // Assign a new student to p
    } // p is not destroyed
    std::cout << p.firstname << ' ' << p.lastname << std::endl;
    return 0;
}

Using pointers you can create a new object on the free-store, but you have to remember to delete it

#include <iostream>
#include <string>

class Student
{
public:
    std::string lastname, firstname;
};

int main()
{
    Student *p = (2 < 3) ? new Student : nullptr;
    if(p != nullptr)
        std::cout << p->firstname << ' ' << p->lastname << std::endl;
    delete p; // Remember to clean up
    return 0;
}

Using unique_ptr and RAII (Same as above, but the pointer is wrapped in a unique_ptr, which will delete your student automatically when it goes out of scope)

#include <iostream>
#include <string>
#include <memory>
class Student
{
public:
    std::string lastname, firstname;
};
int main()
{
    std::unique_ptr<Student> p = (2<3) ? std::make_unique<Student>() : nullptr;
    if (p != nullptr)
        std::cout << p->firstname << ' ' << p->lastname << std::endl;
    return 0;
} // Student is automatically deleted when the unique_ptr p goes out of scope
Fubert
  • 80
  • 5
  • Ok thankks but what if I don't want to use the vector or I am not allowed to use VEctor – Sayed Abdullah Qutb Dec 12 '18 at 11:59
  • @SayedAbdullahQutb Well, you have to make sure your Student is still in scope while using it. You could default initialize a empty Student outside the if statement and then assign to it depending on your condition. I will update the answer to show what I mean. Also, be careful not to declare a function: `Person p()` is dangerous. If you use [uniform initialization](https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization) you don't have this problem: `Person p{}` – Fubert Dec 12 '18 at 12:35
  • @SayedAbdullahQutb Another options, as bruno already mentioned is his answer, is to use pointers and 'new up' students on the [free-store](https://stackoverflow.com/a/1350833/10729041). I'd not recommend this for beginners, since you have to manage the lifetime of your objects yourself and it is easy to make mistakes. Usually in c++ you use [RAII](https://en.cppreference.com/w/cpp/language/raii) to deal with this problem. – Fubert Dec 12 '18 at 12:49