0

My aim with this program is to have a vector of objects describing various types of vehicles. The base class will have a user defined type variable, while each of the subclasses will have a default value as type(eg Van, Bus, etc.). After some searching I found that the best way to use both base and derived classes in a vector is to use a vector of pointers. Here is a simplified version of the code I wrote:

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

using namespace std;

class Vehicle
{
  public:
  Vehicle();
  ~Vehicle();
  virtual void Initialize(string a,string b, int c, int d, int e, string f);
  void print_details();
  void get_yard(int x);
  string type;

  protected:

  string make_and_model;
  int max_pass;
  int max_load;
  int yard;
  string date;   

};
class Lorry : public Vehicle 
{

public:
    void Initialize(string a="Lorry", string b, int c, int d, int e, string f);

};

int i,count;
std::vector<std::unique_ptr<Vehicle>> arr;


Vehicle::Vehicle()
{
std::cout << "New Entry created." << std::endl;
}

Vehicle::~Vehicle()
{
    std::cout << "Entry closed." << std::endl;
}

void Vehicle::Initialize(string a,string b, int c, int d, int e, string f)
{
    type=a;
    make_and_model=b;
    max_pass=c;         
    max_load=d;
    yard=e;
    date=f;
}

void Lorry::Initialize(string a="Lorry", string b, int c, int d, int e, string f)
{   

    make_and_model=b;
    max_pass=c;         
    max_load=d;
    yard=e;
    date=f;
}
void Vehicle::print_details()
{
    std::cout << "Vehicle Type:"<< type << std::endl;
    std::cout << "Make And Model:"<< make_and_model << std::endl;
    std::cout << "Maximum Passengers:"<< max_pass << std::endl;
    std::cout << "Maximum Load Capacity(in Kg):"<< max_load << std::endl;
    std::cout << "Located Yard:"<< yard << std::endl;
    std::cout << "Date of Arrival(dd-MM-YYYY):"<< date <<"\n"<< std::endl;


}

void new_objects()
{
    std::cout<<"How many entries?"<<std::endl;
    std::cin>>count;
    std:: cout<<"The open yards are: Yard 1, Yard 2, Yard 3"<<std::endl;

        for (i = 0; i < count; i++)
            {
            int vc_choice;
            std::cout<<"What is the vehicle type?"<<std::endl;
            std::cout<<"1.Lorry\n6.Other\n";
            std::cin>>vc_choice;
          
            string a;
            string b;
            int c;
            int d;
            int e;
            string f;
            switch (vc_choice)
            {
                case 1:
                    arr.emplace_back(new Lorry());
                    std::cout<<"Enter the vehicle make and model: "<<std::endl;
                    std::cout << "WARNING: Do NOT use spaces, use underscores." << std::endl;
                    std::cin>>b;
                    std::cin.clear();
                    

                    std::cout<<"Enter the maximum passenger capacity: "<< std::endl;
                    std::cin>>c;
                    std::cin.clear();

                    std::cout<<"Enter the maximum load capacity(Kgs): "<<std::endl;
                    std::cin>>d;

                    std::cout<<"Enter the yard number"<<std::endl;
                    std::cin>>e; 

                    std::cout<<"Enter the date of arrival(dd-mm-yyyy): "<<std::endl;
                    std::cin>>f;
                    

                    arr.Initialize(a,b,c,d,e,f);
                    break;
                
                default:
                    arr.emplace_back(new Vehicle());
                    std::cout<<"Enter the vehicle type: "<<std::endl;
                    std::cout << "WARNING: Do NOT use spaces, use underscores." << std::endl;
                    std::cin>>a;

                    std::cout<<"Enter the vehicle make and model: "<<std::endl;
                    std::cout << "WARNING: Do NOT use spaces, use underscores." << std::endl;
                    std::cin>>b;
                    std::cin.clear();
                    

                    std::cout<<"Enter the maximum passenger capacity: "<< std::endl;
                    std::cin>>c;
                    std::cin.clear();

                    std::cout<<"Enter the maximum load capacity(Kgs): "<<std::endl;
                    std::cin>>d;

                    std::cout<<"Enter the yard number"<<std::endl;
                    std::cin>>e;  

                    std::cout<<"Enter the date of arrival(dd-mm-yyyy): "<<std::endl;
                    std::cin>>f;
                    

                    arr.Initialize(a,b,c,d,e,f));
                break;
            }  
            
        }

}
void print_all()
{
    for (int a= 0; a<5; i++)
    {
    arr[a].print_details();
    
    }

}


int main()
{
    new_objects();
    print_all();
    return 0;
} 

Trying to compile it I get this error:

[test unique_ptr.cpp 2021-04-24 06:59:33.521]
,,test unique_ptr.cpp: In function 'void new_objects()':
test unique_ptr.cpp:122:29: error: 'class std::vector<std::unique_ptr<Vehicle> >' has no member named 
'Initialize'
 122 |                         arr.Initialize(a,b,c,d,e,f);
     |                             ^~~~~~~~~~
test unique_ptr.cpp:151:29: error: 'class std::vector<std::unique_ptr<Vehicle> >' has no member named 
   'Initialize'

 151 |                         arr.Initialize(a,b,c,d,e,f));
     |                             ^~~~~~~~~~
test unique_ptr.cpp: In function 'void print_all()':
test unique_ptr.cpp:162:16: error: '__gnu_cxx::__alloc_traits<std::allocator<std::unique_ptr<Vehicle> >,  
std::unique_ptr<Vehicle> >::value_type' {aka 'class std::unique_ptr<Vehicle>'} has no member named   
'print_details'
162 |         arr[a].print_details();
    |                ^~~~~~~~~~~~~

I've tried using the arrow operator but this still doesn't work, as arr is not a pointer. How can I get the program to run?

Ian K
  • 91
  • 4
  • 1
    Have a look at how to make a [mcve]. This error could be reproduced with about 10 lines of code. – super Apr 24 '21 at 07:39
  • The error is self-explanatory. `arr` is a vector. The things *in* the vector are the unique pointers you need to invoke members for. The vector itself has no `Initialize` member function. Thus, `arr.Initialize(a,b,c,d,e,f);` is nonsense. And `arr[a].print_details()` tells the compiler to expect that a `std::unique_ptr` has a member `print_details`. It doesn't. What it points to does. `arr[a]->print_details()`. – WhozCraig Apr 24 '21 at 08:23

1 Answers1

2

Three types of errors.

You can't use default value for the 1st argument and leaving the rest alone. Meaning you cannot write void Initialize(string a="Lorry", string b, int c, int d, int e, string f);. You can write:

void Initialize(string a, string b, int c, int d, int e, string f)

or

void Initialize(string a, string b, int c, int d, int e, string f="Lorry")

or

void Initialize(string a, string b, int c, int d, int e = 0, string f="Lorry")

& the second one is you can't use . to access the method from a pointer, instead you need to use ->. read the thread. The third one is you are calling Initialize from a vector. You need to specify the index to indicate its element. You need to write:

arr[arr.size() - 1]->Initialize(a, b, c, d, e, f);

......

arr[a]->print_details();
Shamsul Arefin
  • 661
  • 7
  • 15