List iterator outside range - c++

I have a problem with the STL list class. I have a base class called Contact, and three derived classes, Friend, Colleague and Acquaintance. Each instance of the derived classes has certain fields which I modify in the fill*Class*Details() function. The problem is that when it reaches the push_back line, my program gives me an error saying list insert iterator outside range. What can that be from?
void Agenda::pushContact(string line, string temp)//function that adds a contact of type temp, containing the fields from line to the list
{
Contact *c;
if(temp=="friend") //the contact to add is of type friend
{
c = new Friend();
fillFriendDetails(c,line);//the details of Friend c will be filled
}
else if(temp=="colleague")
{
c = new Colleague();
fillColleagueDetails(c,line);//the details of Colleague c will be filled
}
else if(temp=="acquaintance")
{
c = new Acquaintance();
fillAcquaintanceDetails(c,line);//the details of Acquaintance c will be filled
}
contactList.push_back(c);
}
Also, the contactList is defined as list <Contact*> contactList;.
Edit: This is how the Contact class (+derived classes) are defined:
class Contact
{
public:
string getFullName() { string fullName;fullName.append(firstName); fullName.append(" ");fullName.append(lastName); return fullName;}
public:
void setFullName(string newFirstName, string newLastName) { firstName = newFirstName; lastName = newLastName;}
public:
string getFirstName() { return firstName;}
public:
void setFirstName(string newFirstName) {firstName = newFirstName;}
public:
string getLastName(){return lastName;}
public:
void setLastName(string newLastName){lastName = newLastName;}
public:
string getPhoneNo(){return phoneNo;}
public:
void setPhoneNo(string newPhoneNo) {phoneNo = newPhoneNo;}
public:
void setType(string newType){type=newType;}
public:
string getType(){return type;}
private:
string firstName;
string lastName;
string phoneNo;
string type;
//SubClass setters and getters
public:
virtual void setDateOfBirth(string birth) {}
virtual string getDateOfBirth() {return 0;}
virtual void setCity (string newCity) {}
virtual string getCity() {return 0;}
virtual void setFaculty (string newFaculty) {}
virtual string getFaculty() {return 0;}
virtual void setGroup (string newGroup) {}
virtual string getGroup() {return 0;}
virtual void setJob (string newJob) {}
virtual string getJob () {return 0;}
};
class Friend : public Contact
{
public:
void setDateOfBirth(string birth) {dateOfBirth=birth;}
public:
string getDateOfBirth() {return dateOfBirth;}
public:
void setCity (string newCity){city=newCity;}
public:
string getCity(){return city;}
private:
string dateOfBirth;
string city; //current city of residence
};
class Colleague : public Contact
{
public:
void setFaculty (string newFaculty){faculty = newFaculty;}
public:
string getFaculty(){return faculty;}
public:
void setGroup (string newGroup){group = newGroup;}
public:
string getGroup(){return group;}
private:
string faculty;
string group;
};
class Acquaintance : public Contact
{
public:
void setJob (string newJob){job=newJob;}
public:
string getJob (){return job;}
private:
string job;
};

It looks like the list is being mismanaged at a different point in the code, because the error implies end is incorrect. Most likely either the list is deleted/out of scope or some incorrect erases were performed on the list elements (say using invalid iterators).

Related

can someone please explain what is wrong in this c++ code and provide a solution

I have declared a class Products and another class CD the class CD is inheriting the class Products.
Now I have declared an constructor to update the value of the. and I am getting an error
#include <iostream>
#include <string>
class Products
{
private:
std::string name;
std::string type;
double price;
public:
virtual std::string getname();
virtual double getprice();
virtual void show();
std::string gettype()
{
return type;
}
};
class CD: public Products
{
private:
std::string artist;
std::string studio;
public:
CD(std::string sname,double sprice,std::string sartist,std::string sstudio)
{
this->type = "CD";
this->name = sname ;
this->price = sprice;
this->artist = sartist;
this->studio = sstudio;
}
void show()
{
std::cout<<"\nName of the CD:\t"<<this->name;
std::cout<<"\nArtist of the CD:\t"<<this->artist;
std::cout<<"\nStudio of the CD:\t"<<this->studio;
std::cout<<"\nPrice of the cd:\t"<<this->price;
}
};
int main()
{
CD obj("Oceans",49,"somesinger","somestudio");
}
ERROR :
In constructor 'CD::CD(std::string, double, std::string)';
'std::string Products::type' is private within this context
this->type="CD";
'std::string Products::name' is private within this context
this->name=sname;
'double Products::price' is private within this context
this->price= sprice;
Basically it is not giving error for the private data members of the CD class but just the data members that are being inherited from Products Class
#include <iostream>
#include <string>
class Products
{
private:
std::string m_name;
std::string m_type;
double m_price;
public:
// No need for your setters/getters to be virtual
// if the derived class won't override anything or not
const std::string& getType() const { return m_type; }
const std::string& getName() const { return m_name; }
double getPrice() const { return m_price; }
void setType(const std::string& new_type) { m_type = new_type; }
void setName(const std::string& new_name) { m_name = new_name; }
void setPrice(double new_price) { m_price = new_price; }
// Force derived class to override function
virtual void show() = 0;
};
class CD: public Products
{
private:
std::string artist;
std::string studio;
public:
CD(std::string sname,double sprice,std::string sartist,std::string sstudio)
{
this->setType("CD");
this->setName(sname) ;
this->setPrice(sprice);
this->artist = sartist;
this->studio = sstudio;
}
void show()
{
std::cout<<"\nName of the CD:\t"<<this->getName();
std::cout<<"\nArtist of the CD:\t"<<this->artist;
std::cout<<"\nStudio of the CD:\t"<<this->studio;
std::cout<<"\nPrice of the cd:\t"<<this->getPrice();
}
};
int main()
{
CD obj("Oceans",49,"somesinger","somestudio");
obj.show();
}
I want you to understand some changes here. First the removal of virtual keyword. In your case the setters/getters had no need to be virtual, as they were not being overriden or didn't have a need to be based on the current example. Second, the setters/getters are setup to access the private members accordingly. We now use these functions within class CD. Also we changed the function show() to be pure virtual notice the = 0 at the end. I added a comment saying this forces derived classes to override the function. Lastly, your main wasn't doing anything so I added a obj.show() to actually print something.
In this solution, I've added a constructor for Products, and CD's constructor calls it to initialize the members that are private to Products.
I removed the virtual on getName and getPrice since these features don't change other products.
show remains virtual, and I split it into a piece in Products and a piece in CD so they each display their respective fields. This separates the printing according to where the variables are, so for example, another class derived from Products wouldn't have to reimplement printing of name and price.
#include <iostream>
#include <string>
class Products
{
private:
std::string name;
std::string type;
double price;
public:
std::string getname(); // Does not need to be virtual, as it's not overriden
double getprice(); // Also does not need to be virtual
virtual void show() const {
std::cout<<"\nName of the " << type << ":\t"<<this->name;
std::cout<<"\nPrice of the " << type << ":\t"<<this->price;
};
Products (const std::string &stype, double sprice, const std::string &sname)
: name (sname), type (stype), price (sprice) {
}
std::string gettype() const
{
return type;
}
};
class CD: public Products
{
private:
std::string artist;
std::string studio;
public:
CD(const std::string &sname,double sprice, const std::string &sartist, const std::string &sstudio)
: Products ("CD", sprice, sname)
{
artist = sartist;
studio = sstudio;
}
void show() const override
{
Products::show(); // Call parent show() to show the basics
std::cout<<"\nArtist of the " << gettype() << ":\t"<<this->artist;
std::cout<<"\nStudio of the " << gettype() << ":\t"<<this->studio;
}
};
int main()
{
Products shoe ("Shoe", 3.49, "Nike runner");
shoe.show();
CD obj("Oceans",49,"somesinger","somestudio");
obj.show();
}

C++ a way to get all inherited classes info

So i have this part of code
class Robot
{
public: string Name;
public: explicit Robot(const string& Name) { this->Name = Name; }
public: Robot() { Name = "Robotic"; }
public: virtual ~Robot() = default;
public: virtual vector<string> GetCapabilities() = 0;
public: friend ostream& operator << (ostream&, const Robot&);
};
class TalkingRobot : virtual public Robot
{
public: explicit TalkingRobot(const string& Name) { this->Name = Name; }
public: virtual ~TalkingRobot() = default;
public: vector<string> GetCapabilities() { return { "Talking" }; }
};
class WalkingRobot : virtual public Robot
{
public: explicit WalkingRobot(const string& Name) { this->Name = Name; }
public: virtual ~WalkingRobot() = default;
public: vector<string> GetCapabilities() { return { "Walking" }; }
};
class VaxBot : public TalkingRobot, public WalkingRobot
{
public: explicit VaxBot(const string& Name):TalkingRobot(Name), WalkingRobot(Name) { this->Name = Name; }
public: virtual ~VaxBot() = default;
public: vector<string> GetCapabilities() { return { "Talking","Walking" }; }
};
They have a virtual function GetCapabilites().
Is there a way to rewrite GetCapabilites() in my VaxBot class to return all the inherited classes return values so that i dont have to explicitly write them like i did in here?
There isn't a simple one-line way in standard C++ to implement this sort of thing. For example, there is no way for a derived class to iterate over all its base classes, and call some member function in every base to collect the results, without explicitly naming all the bases/members separately.
It is possible to call the inherited functions, and collect their results into a single vector. For example;
std::vector<std::string> VaxBot::GetCapabilities()
{
std::vector<std::string> values(TalkingRobot::GetCapabilities());
std::vector<std::string> more_values(WalkingRobot::GetCapabilities());
values.insert(values.end(), more_values.begin(), more_values.end());
return values;
}
The above can be extended if you have more than two such bases. That means explicitly replicating code but, as I said in my opening paragraph, there is no way to implement this sort of machinery implicitly.
There are other problems with your code, but you haven't asked about those, so I won't address them. And, for readability, don't use the text public: on every line. Posting code that is unnecessarily unreadable is an effective way to reduce your chances of getting useful help, since it sets other people's teeth on edge.
class Robot
{
public: string Name;
public: vector<string> Capabilities;
public: explicit Robot(const string& Name) { this->Name = Name; }
public: Robot() { Name = "Robotic"; }
public: virtual ~Robot() = default;
public: vector<string> GetCapabilities() { return this->Capabilities; }
public: friend ostream& operator << (ostream&, const Robot&);
};
class TalkingRobot : virtual public Robot
{
public: explicit TalkingRobot(const string& Name) {
this->Name = Name;
this->Capabilities.push_back("Talking");
}
public: virtual ~TalkingRobot() = default;
};
class WalkingRobot : virtual public Robot
{
public: explicit WalkingRobot(const string& Name) {
this->Name = Name;
this->Capabilities.push_back("Walking");
}
public: virtual ~WalkingRobot() = default;
};
class VaxBot : public TalkingRobot, public WalkingRobot
{
public: explicit VaxBot(const string& Name):TalkingRobot(Name), WalkingRobot(Name) { this->Name = Name; }
public: virtual ~VaxBot() = default;
};
You could utilize multiple inheritance constructors to store Capabilities.

How can I write a dynamic heterogenous collection inside C++ without using STL?

Basically I have to store different movies in a heterogenous collection dynamically, I already have the different movie types (documentary and family) and the class which "masks" the difference (movie) so it can be stored in one place (record).
I'm having trouble with my addMovie(Movie *mov) function. I don't know how to start.
My Record class:
class Record {
String name;
size_t siz;
Movie* movies;
Record(const Record&);
Record& operator=(const Record&);
public:
Record(String n): name(n), siz(0) {movies = new Movie[siz+1];}
void addMovie (Movie *mov);
void removeMovie (Movie *mov);
void listMovies();
void searchMovie (const char* title);
void emptyRecord();
void writeFile();
void readFile();
virtual ~Record() {emptyRecord();}
};
Movie class:
class Movie {
protected:
String name;
String release;
String genre;
public:
Movie(){}
Movie(String n, String r, String g): name(n), release(r), genre(g) {}
virtual void write() {}
virtual ~Movie() {}
};
Documentary class: (the family class is similar, it stores an int age_restriction and the write function writes that)
class Documentary: public Movie {
String description;
public:
Documentary(String n, String r, String d = "Add description up to 50 characters!"): Movie(n,r,"Documentary"), description(d) {}
String getDescription () const {return description;}
void setDescription (String newdescr);
void write();
virtual ~Documentary(){}
};
(PS: if you have any good sources for dynamic heterogenous stores I'm all ears)
Not so clear requirements, but for storing heterogeneous data in one single container, I would advise std::tuple (https://en.cppreference.com/w/cpp/utility/tuple). Let me know if it's what you were looking for ;)
EDIT: a possible solution without STL.
#include <iostream>
using namespace std;
class Base {
};
class A : public Base {
};
class B : public Base {
};
int main(){
const size_t arraySize = 10;
Base* array[arraySize];
//allocate
array[0] = new A();
array[1] = new B();
// ...some more stuff here
//dispose
for (Base* ptr : array) {
if (ptr != nullptr) {
delete ptr;
ptr = nullptr;
}
}
}

How to change a class to another class which derive from the same base class?

I have a base class called Animal:
class Animal {
protected:
std::string name;
int age;
int weight;
public:
Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
virtual void animal_cange(Animal*) = 0;
};
and from the Animal class derives two sublasses
class Dog : public Animal {
public:
Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange(Animal* poot) override {
this = new Cat(poot->name,poot->age,poot->weight);
}
};
and this
class Cat : public Animal {
public:
Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange(Animal* poot) override {
this = new Dog(name, age, weight);
}
};
I made a virtual funcion in the base class caled virtual void animal_cange(Animal*) = 0; which should change a Dog object to a Cat object if it is called with the object's already existing name, age and weight value and visa versa but it always gives me error like:
assignment to 'this' (anachronism)
a value of type "Cat *" cannot be assigned to an entity of type "Dog *"
protected member "Animal::name" (declared at line 12) is not accessible through a pointer or object
I also tried without animal_change being a virtual function like this:
class Animal {
protected:
std::string name;
int age;
int weight;
public:
Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
};
class Dog : public Animal {
public:
Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange() {
this = new Cat(this->name,this->age,this->weight);
}
};
class Cat : public Animal {
public:
Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange() {
*this = new Dog(name, age, weight);
}
};
And the erorrs i get:
this = new Cat(this->name,this->age,this->weight); : "assignment to 'this' (anachronism)" and the entity error
"no operator matches these operands operand types are: Cat = Dog *"
In general, you cannot assign an object to one of a different class - that's what static type system is about. To "change" the dynamic type of a polymorphic object the client code can create another one like this:
Animal* animal = new Dog{}; // actually you should use smart pointers
if (want_to_change) {
delete animal; // prevents a memory leak; smart pointers perform it automatically
animal = new Cat{};
}
If you would like actual animal type choice to happen during initialization, consider using a factory:
class Factory {
public:
// may be static if uses no state, than you can just write a free function
Animal* produce(/* some parameters */) const;
};
Animal* Factory::produce(/* some parameters */) const {
if (should_be_cat(/* depending on the parameters */)) {
return new Cat{};
} else {
return new Dog{};
}
}

How can I override a virtual function in a derived class?

I am trying to build a zoo for practicing c++ and oop. I have made 2 classes, Animal class (the base class) and Bear class (the derived class). I want to have 2 virtual functions in Animal that I will override in Bear but CLION tells me that 'Function Walk did not decleared in class Bear'.
What do I need to change?
This is the base class (Animal) header:
class Animal {
public:
Animal();
Animal(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment);
virtual void Talk() = 0;
virtual void Walk();
int CageNum;
string FoodType;
string Gender;
bool NeedTreatment;
string Name;
};
CPP:
Animal::Animal() {};
Animal::Animal(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment) :
Name(Name), CageNum(CageNum), FoodType(FoodType), Gender(Gender), NeedTreatment(NeedTreatment){};
This is the derived class (Bear) header:
#include "Animal.h"
class Bear : public Animal{
protected:
string FurColor;
public:
Bear(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment,string FurColor);
};
and this is the CPP:
#include "Bear.h"
Bear::Bear(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment,string FurColor) :
Animal(Name, CageNum, FoodType, Gender, NeedTreatment),FurColor(FurColor) {};
void Bear::Walk() {
cout << "Bear Moves";
}
void Animal::Talk() {
"Bear Noise";
}
If you define a function like
void Bear::Walk() {
cout << "Bear Moves";
}
its declaration must appear in the class definition:
class Bear : public Animal{
protected:
string FurColor;
public:
Bear(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment,string FurColor);
void Walk() override; // <<<<<<<<<<<<<<<<<<
};
Alternatively you can omit the definition, and the base class member definition Animal::Walk() will be used.
Also
void Animal::Talk() {
"Bear Noise";
}
is wrong (or at last doesn't do what is intended).
A pure virtual function like Talk() from the base class, must have a declaration and definition in the Bear class, unless the class is intentionally left abstract.
class Bear : public Animal{
protected:
string FurColor;
public:
Bear(string Name, int CageNum, string FoodType, string Gender, bool NeedTreatment,string FurColor);
void Talk() override; // <<<<<<<<<<<<<<<<<<
void Walk() override;
};
and the definition
void Bear::Talk() {
"Bear Noise";
}