I have a class called figGeom. The class circulo inherits from figGeom.
I need to create a class that allows me to save object pointers of type figGeom in an array. Can you help me?
I am also interested to know how to add pointers or memory addresses to the array.
Note: I have also rectangle and triangle classes, but I removed those to make the post shorter and more readable.
My current code gives me an error.
figuraGeom.h
#define TRIANGULO 0
#define RECTANGULO 1
#define CIRCULO 2
class figGeom
{
double area;
int tipoFig;
public:
figGeom();
figGeom(int);
void setArea(double);
double getArea();
void setTipoFig(int);
int getTipoFig();
virtual double calcArea()=0;
virtual void toString()=0;
};
class circulo:public figGeom
{
//atributos
double radio;
public:
circulo();
circulo(double);
void setRadio(double);
double getRadio();
double calcArea();
void toString();
};
figuraGeom.cpp
#include "figuraGeom.h"
#define _USE_MATH_DEFINES
#include <Math.h>
#include <string>
#include <iostream>
using namespace std;
//FIGGEOM
//Dispositivo
figGeom::figGeom(){}
figGeom::figGeom(int itipoDis){
setTipoFig(itipoDis);
}
void figGeom::setArea(double iArea){area = iArea;}
double figGeom::getArea(){return area;}
void figGeom::setTipoFig(int iTipoDis){tipoFig = iTipoDis;}
int figGeom::getTipoFig(){return tipoFig;}
//CIRCULO
circulo::circulo(){}
circulo::circulo(double iRadio):figGeom(CIRCULO){setRadio(iRadio);}
void circulo::setRadio(double iRadio){radio = iRadio;}
double circulo::getRadio(){return radio;}
double circulo::calcArea(){return M_PI*pow(getRadio(),2);}
void circulo::toString(){cout << endl << endl << " Tipo Figura: Circulo" << endl << endl;}
//LISTA FIGURAS
listaFiguras::listaFiguras(){
*lista = NULL;
setNumElementos(0);
}
listaFiguras::~listaFiguras(){
vaciarLista();
}
void listaFiguras::setNumElementos(int iNum){numElementos = iNum;}
int listaFiguras::getNumElementos(){return numElementos;}
void listaFiguras::vaciarLista()
{
free(lista);
}
main.cpp
#include "figuraGeom.h"
#include <iostream>
using namespace std;
int tipoFig;
char opcion;
figGeom * dI = NULL;
listaFiguras* listaFig = new listaFiguras();
void menu();
void menu_add_figura();
figGeom* pedirTriangulo();
figGeom* pedirRectangulo();
figGeom* pedirCirculo();
void menu();
void main()
{
setlocale(LC_ALL, ""); //Configuración Regional
menu();
}
void menu()
{
do{
cout << "SELECCIONA UNA OPCIÓN" << endl;
cout << " [1]Añadir elemento" << endl;
cout << " [2]Ver elemento" << endl;
cout << " [3]Eliminar elemento" << endl;
cout << " [4]Ver todos los elementos" << endl;
cout << " [5]Eliminar todos los elementos" << endl << endl;
cout << " [6]Salir" << endl << endl;
cout << "Opción: ";
cin >> opcion;
switch (opcion){
case '1':
menu_add_figura();
break;
case '2':
break;
case '3':
break;
}
}while(opcion != '6');
}
void menu_add_figura()
{
do{
system("cls"); //limpiamos pantalla
cout << "¿Qué tipo de figura desea crear?" << endl;
cout << " [1]Triangulo" << endl;
cout << " [2]Rectangulo" << endl;
cout << " [3]Circulo" << endl;
cout << " [4]Salir" << endl << endl;
cout << "Figura: ";
cin >> opcion;
//PUNTERO AUX
//listaFiguras-
int new_numElem = (listaFig->getNumElementos()) + 1;
listaFig->setNumElementos(new_numElem);
figGeom** vector = new figGeom*[new_numElem];
switch (opcion){
case '1':
dI = pedirTriangulo(); //dI
*vector[new_numElem-1] = *dI;
break;
case '2':
dI = pedirRectangulo(); //dI
*vector[new_numElem-1] = *dI;
break;
case '3':
dI = pedirCirculo(); //dI
*vector[new_numElem-1] = *dI;
break;
}
if(opcion != '4')
{
//cout << endl << " Area: " << dI->calcArea() << endl << endl; //Mostrar area
cout << endl << " Area: " << vector[new_numElem-1]->calcArea << endl << endl; //Mostrar area
system("pause"); //pausa
system("cls"); //limpiamos pantalla
}else delete dI;
}while(opcion != '4');
}
figGeom* pedirCirculo()
{
int radio;
cout << " -Radio: ";
cin >> radio;
figGeom* dIaux;
dIaux = new circulo(radio);
return dIaux;
}
Don't use raw pointers. Using raw pointers often leads to memory leaks. Instead, use C++11's (or Boost's) various smart pointer classes such as std::unique_ptr or std::shared_ptr. They will handle the issue of deleting objects when they're no longer needed.
#include <memory>
std::shared_ptr<figGeom> createFigure()
{
std::shared_ptr<figGeom> thing(new figGeom(/* whatever */));
return thing;
}
You don't need to use a simple array, and you certainly don't need to write your own container class. Instead, use one of the many containers from the standard library... they're fast, efficient, handle their own memory allocation and deallocation and perhaps most importantly, they've been well tested. std::vector or std::array woudl work just fine... use vectors when you only know the size of the container at runtime, and arrays when you know the size of the container at compile time. Both containers can be accessed in the same way as a standard simple array.
#include <vector>
std::vector<std::unique_ptr<figGeom>> createFigures()
{
std::vector<std::unique_ptr<figGeom>> figures;
figures.push_back(createFigure());
figures[0].setArea(1234.56);
return figures;
}
With such a simple, lightweight class as this, you don't really need to use new at all... you can allocate instances on the stack, and just copy them into a container when needed.
figGeom createShape()
{
figGeom shape(/* whatever */);
return shape;
}
std::vector<figGeom> createShapes()
{
std::vector<figGeom> shapes;
shapes.push_back(createShape());
return shapes;
}
You can do this:
figGeom* array[10];// change 10 to any number you need
then create pointer to circulo class and save it in the array
for(int i=0;i<10;i++){
array[i] = new circulo(/*parameters to constructor*/);
}
after you done with the objects, you should free the memory
for(int i=0;i<10;i++){
delete array[i];// Note, your destructor in figGeom class should be virtual
}
Related
I have a class of light bulbs. There are methods and constructors in this class. There is even a destructor) The problem is that I have to determine and display information about class members with type "n" in the TEST() method (LED lamps).
To implement this task, he developed the gettype() method, which returns the type of an object, and, in fact, the TEST() method, which displays information about light bulbs.
The problem is that nothing works for me. I tried a lot of things, but it doesn’t work out for me to implement this task. I'm new to programming (
Code:
#include <iostream>
using namespace std;
class lamp
{
public:
// methods
void TEST(void);
char* gettype (void);
void INIT(void);
void SHOW(void);
// construcrors
lamp();
lamp(const char *t, int powe, const char *c, double cos);
lamp(const lamp & obj);
// destructor
~lamp();
private:
// data
char type[100]; // LED, energy-saving or incandescent lamp
int power; // LED lamp - "n"
char color[100];
double cost;
};
lamp::lamp() {
cout << "This object was created in the default constructor.\n";
strcpy(type, "");
power = 0;
strcpy(color, "");
cost = 0;
}
lamp::lamp(const char *t, int powe, const char *c, double cos) {
cout << "This object was created in the constructor with parameters.\n";
strcpy(type, t); //*t
power = powe;
strcpy(color, c); //*c
cost = cos;
}
lamp::lamp(const lamp & obj) {
cout << "This object was created in the copy constructor.\n";
strcpy(type, obj.type);
power = obj.power;
strcpy(color, obj.color);
cost = obj.cost;
}
lamp::~lamp() {
cout << "Deletion of object by destructor.\n";
}
void lamp::SHOW(void) {
cout << "Lamp Information:\n";
cout << "\nType > " << type;
cout << "\nPower > " << power;
cout << "\nColor > " << color;
cout << "\nCost > " << cost << endl;
}
void lamp::INIT(void) {
cout << "Enter lamp information:\n";
cout << "\nType (if LED, then n) > "; cin >> type;
cout << "\nPower > "; cin >> power;
cout << "\nColor > "; cin >> color;
cout << "\nCost > "; cin >> cost;
}
char* lamp::gettype (void) {
return type;
}
void lamp::TEST(void) {
cout << "\nType > " << type;
cout << "\nPower > " << power;
cout << "\nColor > " << color;
cout << "\nCost > " << cost << endl;
}
void main() {
setlocale(0, "");
// default constructor for 1 class instance
lamp l1;
cout << "Entering data for the first product." << endl;
l1.INIT();
// constructor with parameters for 2 class instances
cout << endl << "Information about the second object: \n";
lamp l2("n", 950, "yellow", 1580);
// copy constructor for the third object
cout << endl << "Information about the third object: \n";
lamp l3(l2);
// Derived information about all the lamps using the method SHOW
l1.SHOW();
l2.SHOW();
l3.SHOW();
// I create an array of two objects using the default constructor
lamp la[2];
I enter data into an array of objects using the method INIT
cout << "Fill an array of objects with 2 elements." << endl;
for(int i = 0; i < 2; i++) {
la[i].INIT();
}
// I output data from an array of objects using the method SHOW
cout << "Showing items." << endl;
for (int i = 0; i < 2; i++) {
la[i].SHOW();
}
// looking for and displaying information about LED lamps
cout << "Search and display information about LED lamps." << endl;
for (int i = 0; i < 3; i++) {
if (la[i].gettype() == "n") {
cout << endl << " lamp number : " << (i + 1) << endl;
la[i].TEST();
cout << endl;
}
}
system("pause");
}
There are several errors in your code:
strcpy is included in <cstring> which is missed. You need to add it in the beginning:
#include <cstring>
main() function should be declared as int main() and you need to add a return statement
int main() {
//YOUR CODE HERE
return 0;
}
You missed a comment sign at line 104
lamp la[2];
//I enter data into an array of objects using the method INIT
cout << "Fill an array of objects with 2 elements." << endl;
After fixed, your code should be able to run.
Hi this is the header file for my base class Ranger, and in it I have protected variables fov_, usb_ ... that I wish to access with my getter functions, I have three child classes on this one.
Ranger.h
#ifndef RANGER_H
#define RANGER_H
using namespace std;
class Ranger
{
//private contructor prevents contruction of base class
Ranger();
public:
void setBaud(int baud);
virtual void setFOV(int fov) = 0;
void setSamp(int sam);
int getFOV();
int getBaud();
int getMaxRange();
int getUSB();
protected:
//protected variables that are each indivdualy owned by each sensor
int fov_;
int maxRange_;
int usb_;
int baud_;
int samp_;
double data[];
//protected contructors for the child classes to use to set fixed parameters
Ranger(int fov, int maxRange, int port);
Ranger(int maxRange, int port);
};
#endif // RANGER_H
This is my cpp file for the base class that includes the getter files, it just has a return of the portected variables.
Ranger::Ranger()
{
}
Ranger::Ranger(int fov, int maxRange, int port)
{
fov_ = fov;
maxRange_ = maxRange;
usb_ = port;
}
Ranger::Ranger(int maxRange, int port)
{
maxRange_ = maxRange;
usb_ = port;
}
void Ranger::setBaud(int baud)
{
switch(baud)
{
case 0: baud_ = 38400; break;
case 1: baud_ = 115200; break;
default: baud_ = 38400; break;
}
}
void Ranger::setSamp(int sam)
{
samp_ = sam;
}
int Ranger::getFOV()
{
return fov_;
}
int Ranger::getBaud()
{
return baud_;
}
int Ranger::getMaxRange()
{
return maxRange_;
}
int Ranger::getUSB()
{
return usb_;
}
And in my main I want to access the protected variables from the base class to prevent re writting code, so each childs variables are protected in the base class. I try to access these by las.getFOV() but I get a segmentation fault error meaning I don't have access to them, and I don't quite understand why.
main.cpp
int main( int argc, char ** argv)
{
Laser las;
int baud;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud;
las.setBaud(baud);
cout << "Baud for Lazer sensor is "+las.getBaud() << endl;
cout << "Lazer sensor created..." << endl;
cout << "Lazer's FOV: " + las.getFOV() << endl;
cout << "Lazer's Max Range: " + las.getMaxRange() << endl;
cout << "Lazer's Port: " + las.getUSB() << endl;
Radar rad;
int baud2;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud2;
rad.setBaud(baud2);
cout << "Baud for Radar sensor is "+rad.getFOV() << endl;
int fov;
cout << "Feild of View Of Radar:" << endl;
cout << "0 - 20 degrees" << endl;
cout << "1 - 40 degrees" << endl;
cin >> fov;
rad.setFOV(fov);
cout << "FOV is set to " + rad.getFOV() << endl;
cout << "Radar sensor created..." << endl;
cout << "Radar's FOV: ' " + rad.getFOV() << endl;
cout << "Radar's Max Range: " + rad.getMaxRange() << endl;
cout << "Radar's Port: " + rad.getUSB() << endl;
Sonar son;
//rad.setFOV(user);
}
and here is one of the child class's cpp file for reference (Lazer)
laser.cpp
#include "laser.h"
Laser::Laser() : Ranger(180,8,0)
{
};
void Laser::setFOV(int fov)
{
fov_ = fov;
}
laser.h
#ifndef LASER_H
#define LASER_H
#include "ranger.h"
#include "rng.h"
class Laser : public Ranger
{
public:
Laser();
void setFOV(int fov);
};
#endif // LASER_H
Thanks everyone who commented, I understand I put way too much code to help you guys out, sorry about that I'll know for next time, and thankyou to letting me know the difference between the errors, I've done more research and found that the issue was when I was printing it out you can't use operators like:
cout<<""+function()<<endl;
Instead you need to separate the functions from the array like so:
cout<<""<<function()<<endl;
Thanks guys.
I am asked to do this code and i need to use array or something similar to print out different classes. The only way i know is individually doing every single class is there a faster way of doing this. Following is the way i am using at the moment.
Ground_Transport Gobj;
Air_Transport Aobj;
Sea_Transport Sobj;
Car Cobj;
Train Tobj;
Bus Bobj;
Gobj.estimate_time();
Gobj.estimate_cost();
cout << Gobj.getName() << endl;
Bobj.estimate_time();
Bobj.estimate_cost();
cout << Bobj.getName() << endl;
Sobj.estimate_time();
Sobj.estimate_cost();
cout<<Sobj.getName()<<endl;
Aobj.estimate_time();
Aobj.estimate_cost();
cout << Aobj.getName() << endl;
Cobj.estimate_time();
Cobj.estimate_cost();
cout << Cobj.getName() << endl;
Tobj.estimate_time();
Tobj.estimate_cost();
cout << Tobj.getName() << endl;
Transport_KL_Penang Kobj;
cout << Kobj.getName() << endl;
This is the header file Transport_KL_Penang
#include <iostream>
#include <string>
using namespace std;
class Transport_KL_Penang
{
public:
Transport_KL_Penang() {}
virtual string getName() {
return Name;
}
int Time_in_hours1 ;
int Time_in_hours2 ;
int Cost_in_RM1 ;
int Cost_in_RM2 ;
void estimate_time() ;
void estimate_cost() ;
private:
static string Name;
};
void Transport_KL_Penang::estimate_time()
{
cout << "It takes " << Time_in_hours1 << "-" << Time_in_hours2 <<
" hours if you use " << Name << endl;
}
void Transport_KL_Penang::estimate_cost()
{
cout << "It will cost around " << Cost_in_RM1 << "-" << Cost_in_RM2 <<
"RM if you use " << Name << endl;
}
If you don't need a specific object name, you can write something as a code below, creating a multiples generics objects:
#include <iostream>
#include <cstdlib>
#include <time.h>
class Myclass {
private:
int randTime;
float cost;
public:
void estimate_time(){
randTime = rand()%100;
}
void estimate_cost(){
cost = randTime * 0.2;
}
float getEstimateCost(){
return cost;
}
};
int main(){
srand(time(NULL));
int numberOfObjects = 7;
Myclass obj[numberOfObjects];
//input
for(int i = 0; i < numberOfObjects; i++){
obj[i].estimate_time();
obj[i].estimate_cost();
}
// printing
for(int i = 0; i < numberOfObjects; i++){
std::cout << obj[i].getEstimateCost() << std::endl;
}
return 0;
}
I have this program, and I'm still getting used to C++ pointers, so It's probably an issue with that. But I am having the program crash when the getStructData() function is called. I've probably messed up something to do with the pointer to the struct that i've used, but I'm really not sure at this point. Any tips or help are appreciated. Thanks, and before people start the mad downvoting, this isn't a homework assignment from my school, I'm just going over other schools homework to practice during the christmas break.
Prog1Struct.h
#ifndef INCLUDED_PROG1STRUCT
#define INCLUDED_PROG1STRUCT
struct Prog1Struct
{
int m_iVal;
double m_dArray[5];
char m_sLine[80];
};
#endif
Prog1Class.h
#ifndef PROG1CLASS
#define PROG1CLASS
#include "Prog1Struct.h"
class Prog1Class
{
private:
Prog1Struct myStruct[5];
public:
/*Prog1Class();
~Prog1Class();*/
void setStructData();
void getStructData(int structureArrayIndex, struct Prog1Struct *info);
void printStruct(int indexPriv);
void printData();
};
#endif
Prog1Class.cpp
#ifndef INCLUDED_PROG1CLASS
#define INCLUDED_PROG1CLASS
#include <iostream>
#include <string>
#include "Prog1Class.h"
#include "Prog1Struct.h"
#include <time.h>
using namespace std;
void Prog1Class::setStructData()
{
for (int i = 0; i<5; i++)
{
cout << "Enter an integer: ";
cin >> myStruct[i].m_iVal;
for (int j = 0; j < 5; j++)
{
cout << endl << "Enter a double: ";
cin >> myStruct[i].m_dArray[j];
}
cout << endl << "Enter a string: ";
cin.ignore(256, '\n');
cin.getline(myStruct[i].m_sLine, 80, '\n');
cout << endl;
}
}
//takes in index for array, and pointer to a struct of the type in Prog1Struct.h. Copies all data from the private struct at the given index into the struct of the pointer argument.
void Prog1Class::getStructData(int structureArrayIndex, struct Prog1Struct *info)
{
*info = myStruct[structureArrayIndex];
cout << "Printing *info from getStructData function" << endl;
cout << info;
}
void Prog1Class::printStruct(int indexPriv)
{
cout << myStruct[indexPriv].m_iVal << " ";
for (int k = 0; k < 5; k++)
{
cout << myStruct[indexPriv].m_dArray[k] << " ";
}
cout << myStruct[indexPriv].m_sLine << " ";
}
int main(void)
{
Prog1Class c;
Prog1Struct *emptyStruct = '\0';
cout << "setStructData called:" << endl;
c.setStructData();
cout << "getStructData called:" << endl;
//error comes here, at getStructData.
c.getStructData(2, emptyStruct);
cout << "printStruct called:" << endl;
c.printStruct(2);
cin.get();
}
#endif
You are trying to assign a value to a null pointer.
Prog1Struct *emptyStruct = '\0';//set emptyStruct to 0 (This means it points at address 0, not holding a 0 value)
cout << "setStructData called:" << endl;
c.setStructData();
cout << "getStructData called:" << endl;
//error comes here, at getStructData.
c.getStructData(2, emptyStruct);//emptyStruct is still = 0
So in the function, info = 0.
void Prog1Class::getStructData(int structureArrayIndex, struct Prog1Struct *info)
{
*info = myStruct[structureArrayIndex];//This line is trying to write to a section of memory you don't have access to (address 0)
I think you want this instead. (untested) This will make info point to myStruct[structureArrayIndex] (Not copy the contents of myStruct[structureArrayIndex] to info). Pointers only point to things (like structs or some other type), they cannot contain a struct.
info = &myStruct[structureArrayIndex];
Here's the code that triggers the error (Player.cpp):
#include "Library.h"
Player::Player(){
//generate player stats
str = rand()%6+1+1;
inte = rand()%6+1;
c = (rand()%6+1)+floor(str/3);
wis = rand()%6+1+floor(inte/4);
ref = rand()%6+1+floor(wis/4);
i = floor(ref/3);
hp = floor((str+(wis/3)+(ref/2)));
xp = 0;
}
//printStats (constant Player player reference)
//prints player's stats
void Player::printStats() const{
cout << "\nSTR: " << str << endl;
cout << "INTE: " << inte << endl;
cout << "C: " << c << endl;
cout << "WIS: " << wis << endl;
cout << "REF: " << ref << endl;
cout << "I: " << i << endl;
cout << "HP: " << hp << endl;
cout << "XP: " << xp << endl;
cout << "Gold: " << gold << endl;
cout << "Level: " << lvl << endl << endl;
}
int Player::giveOptions(int amount,string op1, string op2, string op3, string op4, string op5){
cout << "Type the number then press the enter key to choose or type 'help' for extra commands." << endl;
for(int i=1;i<=amount;i++){
string s;
switch(i){
case 1:
s = op1;
break;
case 2:
s = op2;
break;
case 3:
s = op3;
break;
case 4:
s = op4;
break;
case 5:
s = op5;
break;
}
cout << i << ". " << s << endl;
}
while(true){
string s;
cin >> s;
if (s == "1")
return 1;
else if (s == "2")
return 2;
else if (s == "3")
return 3;
else if (s == "4")
return 4;
else if (s == "5")
return 5;
else{
if (s == "stats")
printStats();
else if (s == "help"){
cout << "Type the number that is next to the option you wish to choose then press the enter key, or 'stats' to print all of your stats." << endl;
cout << "E.G:\n1. Town\nI want to go to the town\n1" << endl;
}
else
cout << "Command not recognised. If you're confused, type 'help'." << endl;
}
}
}
(Original question below)
I'm fairly basic in C++, and I'm not sure why this is producing an error. In Player.cpp, all members of Entity that I thought were inherited produce the error, "x is not a member of Player". My only thought is that I'm using inheritance wrong.
Entity.h:
#include "Library.h"
using namespace std;
class Entity {
public:
void printStats() const;
protected:
//player stats
std::string name;
double str; //strength
double wis; //wisdom
double ref; //reflex
double hp; //health points
double i; //initiative
double inte; //intelligence
double c; //courage
int gold; //gold
int xp; //experience
int ap; //armour points
int wd; //weapon damage
int lvl; //level
int sp; //skill points
};
Player.h
#include "Library.h"
using namespace std;
class Player: public Entity{
public:
Player();
int giveOptions(int amount, string op1, string op2, string op3, string op4, string op5);
};
void Player::printStats() const
Should be, according to your headers:
void Entity::printStats() const
On the includes, do one of these, whichever suits your code best:
1.
Player.h must include Entity.h
Library.h should not include Player.h or Entity.h
Player.h and/or Entity.h can include Library.h if really needed.
or 2.
Player.h must include Entity.h, but not Library.h
Entity.h must not include Library.h
Library.h can include Player.h and/or Entity.h
This avoids the cyclic dependencies you currently have - which leads to Player being defined before Entity and giving the base class undefined error.
As the compiler compliains - neither the class Entity nor the Player has a member variable called x. You need to include "Entity.h" in the Player header file, since in the current translation unit compiler doesn't know what Player is.