shared_ptr to vector of shared_ptr in C++

 When we will go for shared_ptr ?

  1. When we want to access the other concrete class members through an abstract class.
  2. Will be updated.....
Let's test the first usage. ie., while accessing other concrete's class members.

#include <iostream>
#include <memory> // To avoid shared_ptr errors

using namespace std;

#define ENCODE_NUM 73
class ArmyHospital
{
protected:
    int code_;
    int schoolCode_;
public:
    ArmyHospital(int cod) {
       code_ = cod;
    }
    int getHospitalCode() {
       return code_;
    }
    int getSchoolCode() {
       return schoolCode_;
    }
};

class ArmySchool: public ArmyHospital {
    public:
        ArmySchool(int code) : ArmyHospital(code + ENCODE_NUM){ 
            schoolCode_ = code;  
        }
};

class Army  
{
private:
    int armyCode;
    int nameCode;
    std::shared_ptr<ArmyHospital> ptr;

public:    
    Army() {};
    Army(int army, int name) : armyCode(army), nameCode(name){};
    int getArmyCode() {
       return armyCode;
    }
    int getNameCode() {
       return nameCode;
    }
    void addClass(std::shared_ptr<ArmyHospital> hosPtr) {
         this->ptr = hosPtr;
    }
    
    void print() {
        cout << "The Hospital's code is " <<  this->ptr->getHospitalCode() << endl
             << "The School's code is " <<  this->ptr->getSchoolCode()<< endl;
    }
};


int main ()
{
    Army arm1(581, 78);
    //Army arm2(582, 79);
    auto ptr = std::make_shared<ArmySchool>(2);
    arm1.addClass(ptr);
    arm1.print();
    return 1;
}

Output

The Hospital's code is 75
The School's code is 2

Why I need vector, First I tried adding multiple class pointers to the Army's class and print all its values.

#include <iostream>
#include <memory>

using namespace std;

#define ENCODE_NUM 73
class ArmyHospital
{
protected:
    int code_;
    int schoolCode_;
    int universityCode_;
public:
    ArmyHospital(int cod) {
       code_ = cod;
    }
    int getHospitalCode() {
       return code_;
    }
    int getSchoolCode() {
       return schoolCode_;
    }
    int getUniversityCode() {
       return universityCode_;
    }
};

class ArmySchool: public ArmyHospital {
    public:
        ArmySchool(int code) : ArmyHospital(code + ENCODE_NUM){ 
            schoolCode_ = code;  
        }
};

class ArmyUniversity: public ArmyHospital {
    public:
        ArmyUniversity(int code) : ArmyHospital(code + ENCODE_NUM + 2){ 
            universityCode_ = code;  
        }
};

class Army  
{
private:
    int armyCode;
    int nameCode;
    std::shared_ptr<ArmyHospital> ptr;

public:    
    Army() {};
    Army(int army, int name) : armyCode(army), nameCode(name){};
    int getArmyCode() {
       return armyCode;
    }
    int getNameCode() {
       return nameCode;
    }
    void addClass(std::shared_ptr<ArmyHospital> hosPtr) {
         this->ptr = hosPtr;
    }
    
    void print() {
        cout << "The Hospital's code is " <<  this->ptr->getHospitalCode() << endl
             << "The School's code is " <<  this->ptr->getSchoolCode()<< endl 
             << "The University's code is " <<  this->ptr->getUniversityCode() << endl;
    }
};


int main ()
{
    auto schPtr = std::make_shared<ArmySchool>(2);
    auto uniPtr = std::make_shared<ArmyUniversity>(5);
    
    Army arm1(581, 78);
    arm1.addClass(schPtr); // schoolCode_ = 2, code_ = 73 
    arm1.addClass(uniPtr); // universityCode_ = 5, code_ = 80
    
    arm1.print();
    
    return 1;
}

Output

The Hospital's code is 80
The School's code is 0
The University's code is 5

The problem is it took only the last ptr's value, but i want to get the school code as well. 

That's the reason, we need to store all the pointers to some collection. Let's first try to store it in the vectors. 


Convert to a vector of shared_ptr

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

#define ENCODE_NUM 73
class ArmyHospital
{
protected:
    int code_;
    int schoolCode_;
    int universityCode_;
public:
    ArmyHospital(int cod) {
       code_ = cod;
    }
    int getHospitalCode() {
       return code_;
    }
    int getSchoolCode() {
       return schoolCode_;
    }
    int getUniversityCode() {
       return universityCode_;
    }
};

class ArmySchool: public ArmyHospital {
    public:
        ArmySchool(int code) : ArmyHospital(code + ENCODE_NUM){ 
            schoolCode_ = code;  
        }
};

class ArmyUniversity: public ArmyHospital {
    public:
        ArmyUniversity(int code) : ArmyHospital(code + ENCODE_NUM + 2){ 
            universityCode_ = code;  
        }
};

class Army  
{
private:
    int armyCode;
    int nameCode;
    vector<std::shared_ptr<ArmyHospital>> ptr;  // vector change

public:    
    Army() {};
    Army(int army, int name) : armyCode(army), nameCode(name){};
    int getArmyCode() {
       return armyCode;
    }
    int getNameCode() {
       return nameCode;
    }
    void addClass(std::shared_ptr<ArmyHospital> hosPtr) {
         //this->ptr = hosPtr;
         this->ptr.push_back(shared_ptr<ArmyHospital>(hosPtr));  //vector change 2
    }
    
    void print() {
        if (this.ptr.empty()) {
            return;
        }
        for (auto i = this->ptr.begin(); 
             i != this->ptr.end(); i++) {  // Vector new line
           cout << "The Hospital's code is " <<  
                 (*i)->getHospitalCode() << endl   // Vector change
                 << "The School's code is " << 
                 (*i)->getSchoolCode()<< endl    // Vector change
                 << "The University's code is " 
                 <<  (*i)->getUniversityCode() << endl; // Vector change
        }
    }
};


int main ()
{
    auto schPtr = std::make_shared<ArmySchool>(2);
    auto uniPtr = std::make_shared<ArmyUniversity>(5);
    
    Army arm1(581, 78);
    arm1.addClass(schPtr); // schoolCode_ = 2, code_ = 73 
    arm1.addClass(uniPtr); // universityCode_ = 5, code_ = 80
    
    arm1.print();
    
    return 1;
}

Output

The Hospital's code is 75
The School's code is 2
The University's code is 0
The Hospital's code is 80
The School's code is 0
The University's code is 5

How to know shared_ptr's address and number of pointers sharing the same resource?

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

#define ENCODE_NUM 73
class ArmyHospital
{
protected:
    int code_;
    int schoolCode_;
    int universityCode_;
public:
    ArmyHospital(int cod) {
       code_ = cod;
    }
    int getHospitalCode() {
       return code_;
    }
    int getSchoolCode() {
       return schoolCode_;
    }
    int getUniversityCode() {
       return universityCode_;
    }
};

class ArmySchool: public ArmyHospital {
    public:
        ArmySchool(int code) : ArmyHospital(code + ENCODE_NUM){ 
            schoolCode_ = code;  
        }
};

class ArmyUniversity: public ArmyHospital {
    public:
        ArmyUniversity(int code) : ArmyHospital(code + ENCODE_NUM + 2){ 
            universityCode_ = code;  
        }
};

class Army  
{
private:
    int armyCode;
    int nameCode;
    vector<std::shared_ptr<ArmyHospital>> ptr;  // vector change

public:    
    Army() {};
    Army(int army, int name) : armyCode(army), nameCode(name){};
    int getArmyCode() {
       return armyCode;
    }
    int getNameCode() {
       return nameCode;
    }
    void addClass(std::shared_ptr<ArmyHospital> hosPtr) {
         //this->ptr = hosPtr;
         this->ptr.push_back(shared_ptr<ArmyHospital>(hosPtr));  //vector change 2
         cout << "Hospital Ptr's count " << hosPtr.use_count() 
               << " Hospital's address " << hosPtr.get() << endl;
    }
    
    void print() {
         for (auto i = this->ptr.begin(); i != this->ptr.end(); i++ ) {  // Vector new line

            cout << "The Hospital's code is " <<  (*i)->getHospitalCode() << endl
                 << "The School's code is " <<  (*i)->getSchoolCode()<< endl 
                 << "The University's code is " <<  (*i)->getUniversityCode() << endl;
        }
    }
};


int main ()
{
    auto schPtr = std::make_shared<ArmySchool>(2);
    cout << "schPtr's count " << schPtr.use_count() 
         << " schPtr's address " << schPtr.get() << endl;
    auto uniPtr = std::make_shared<ArmyUniversity>(5);
    cout << "uniPtr's count " << uniPtr.use_count() 
         << " uniPtr's address " << uniPtr.get() << endl;
    
    Army arm1(581, 78);
    arm1.addClass(schPtr); // schoolCode_ = 2, code_ = 73 
    arm1.addClass(uniPtr); // universityCode_ = 5, code_ = 80
    
    arm1.print();
    
    return 1;
}

Output

schPtr's count 1 schPtr's address 0x555ba6556ec0
uniPtr's count 1 uniPtr's address 0x555ba6557300
Hospital Ptr's count 3 Hospital's address 0x555ba6556ec0
Hospital Ptr's count 3 Hospital's address 0x555ba6557300
The Hospital's code is 75
The School's code is 2
The University's code is 0
The Hospital's code is 80
The School's code is 0
The University's code is 5


Reference 

















Comments