-1

In the following I would like to replace usage of "new" with smart pointers. However, so far my attempts were not successfully. The commented lines are what I tried to change for smart pointers.

int main(){
    
        int n, val;
        cin>>n; 
        Person* per[n];
        // shared_ptr<Person> per[n];
        for(int i = 0;i < n;i++){
            cin>>val;
            if(val == 1){
                per[i] = new Professor;//shared_ptr<Professor>();
            }
            else {
                per[i] = new Student;//shared_ptr<Student>(); 
            }
            per[i]->getdata();
        }
    
        for(int i=0;i<n;i++)
            per[i]->putdata(); 
    
        return 0;
    
    }

The remaining of the code where the classes are defined is as follows:

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <memory>
    
    using namespace std;
    class Person {
        public:
            int age;
            std::string name;
            int cur_id_this;
            virtual void getdata()  {};
            virtual void putdata() {};
            
            ~Person(){};
    };
    
    class Professor : public Person {
        public:
            int publications;
            static int cur_id;
            Professor(){
                   cout << "init prof " << cur_id << endl;
                    cur_id += 1;
            };
    
            void getdata(){
                cin >> name >> age >> publications;
                cur_id += 1;
                cur_id_this = cur_id;
            }
            void putdata(){
                printf("%s %i %i %i\n", name.c_str(), age, publications, cur_id_this);
            }
    };
    
    class Student : public Person {
        public:
            std::vector<int> marks;
            static int cur_id;
            int cur_id_this;
            int marks_sum;
    
        void getdata(){
            cin >> name >> age;// >> publications;
            int grade;
            for (auto i=0; i<6; ++i){
                cin >> grade;
                marks_sum += grade;
            }
            std::cout << "---" << marks_sum<< endl;
            cur_id += 1;
            cur_id_this = cur_id;
        }
        
        void putdata(){
    
            printf("%s %i %i %i\n", name.c_str(), age, marks_sum, cur_id_this);
        }
            
    };
    
    int Professor::cur_id = 0;
    int Student::cur_id = 0;
    

and the input the above code gets in command line is:

4
1
Walter 56 99
2
Jesse 18 50 48 97 76 34 98
2
Pinkman 22 10 12 0 18 45 50
1
White 58 87
Alejandro
  • 879
  • 11
  • 27
  • What does "not successful" mean? And variable-length arrays aren't standard, so you should probably replace `per[n]` with an `std::vector`. – Stephen Newell May 08 '22 at 13:13
  • And your question is? Regardless, to make an instance of your classes in the `shared_ptr`, not just a `shared_ptr` storing `NULL`, you want `per[i] = std::make_shared();` which both creates the shared ptr and allocates an instance of the class that it points to (in a more efficient and exception-proof manner than `shared_ptr(new Professor)`). – ShadowRanger May 08 '22 at 13:14
  • @ShadowRanger so in general 'make_shared()' would be a better practice than 'shared_ptr(new Professor)' ? – Alejandro May 08 '22 at 13:22
  • @azerila: Yes. It condenses two allocations (one for the `Professor`, one for the `shared_ptr` state management) down to one (a single block allocation containing both components), and in certain cases can protect you from hard-to-test errors that can lead to memory leaks. – ShadowRanger May 08 '22 at 13:51

1 Answers1

1

You're not allocating the actual object, so use std::make_shared :

per[i] = std::make_shared<Student>();

Although make_shared is preferred, you can write:

per[i] = shared_ptr<Professor>(new Professor);
s4eed
  • 7,173
  • 9
  • 67
  • 104
  • between std::make_shared(); and shared_ptr(new Professor); which one is a better practice or what would be a possible difference? – Alejandro May 08 '22 at 13:23
  • 4
    `make_shared` is usually prefered. See here: https://stackoverflow.com/questions/20895648/difference-in-make-shared-and-normal-shared-ptr-in-c – wohlstad May 08 '22 at 13:42