How to Access a Struct Inside a Struct in C++? - c++

I'm trying to access the variables string ModelName and int Sales like this Dealer.Modelo.ModelName but it's not working. How can I access those variables to fill the the structure?
PD: The compiler says that "Dealer" should have a class type.
const int MAXIMODEALERS = 20;
const int MAXIMOMODELOS = 6;
struct Detail
{
string ModelName;
int Sales;
};
struct Element
{
string CompanyName;
Detail Modelo[MAXIMOMODELOS];
};
Element Dealer[MAXIMODEALERS];

Element Dealer[MAXIMODEALERS];
declares an array of objects of type Element, but :
Dealer.Modelo.ModelName = "something";
is treating Dealer as it would be a single instance of Element, neither an array. You need to use an index to access concrete element (same for the Modelo):
Dealer[SomeIndex].Modelo[OtherIndex].ModelName = "something";

Related

Create an instance of an object C++

I have recently picked up C++ but I am having problems in some areas as I am used to Java and I am not sure if I am going about things the right way.
I have a text file which lines are structured like this
C;101;1;1;4;10;
H;102;9;0;1;8;2
C;103;9;9;2;5;
C;104;0;9;3;8;
; being the delimeter
C is used to check if its a Crawler(H is used to check if it is a Hopper), it is then followed by the id, positions, directions(1-4), size, and alive(0/1)
I have an abstract Bug class then I have a Crawler and Hopper class which both inherit from the Bug class.
Here is my Bug class
class Bug
{
public:
int id;
pair<int, int> position;
int direction;
int size;
bool alive;
list<pair<int, int>> path;
virtual void move() {}
bool isWayBlocked() {}
Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
{
type = type;
id = id;
position = position;
direction = direction;
size = size;
alive = alive;
};
};
Here is the Crawler class
class Crawler : public Bug
{
public:
Crawler(int id, pair <int, int> position, int direction, int size)
: Bug("Crawler", id, position, direction, size, alive)
{
}
};
Here is an example of me trying to create an instance of a Crawler object:
Bug* bugPtr;
if (bugType == "C") {
bugPtr = new Crawler(bugID, { xPos,yPos }, direction, size);
//Crawler* CrawlerBugPointer = new Crawler(bugID, { xPos,yPos }, direction, size);
}
I am able to easily read from the text file and store the variables but when i start debugging all of the fields in the bugPtr say 0, I suspect that I have gone about things in completely the wrong way and have not built the Abstract class and Inheritor classes properly, could anyone point out what I am doing wrong? any help will be much appreciated.
The compiler should have generated a warning, "Expression with possibly no effect" (or similar), for every line in your constructor. Read the warnings - they're useful.
Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
{
this->type = type;
this->id = id;
this->position = position;
this->direction = direction;
this->size = size;
this->alive = alive;
};
While C++ doesn't require the ridiculous use of this everywhere, in your case it's necessary since you've given the constructor parameters the same names as the fields. When you enter something like
id = id;
You're saying, "Find the variable with name id in this scope, and assign its value to itself." Which does nothing, which is why all of your fields were left at their default values. Saying this.id means, "Find the class field with name id and assign the value of the local id to it."
The way to do this is with an initializer list:
Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
: type(type), id(id), position(position), direction(direction), size(size), alive(alive)
{ }
The problem with the original code is name hiding. In the constructor body, type = type simply assigns the value of the argument named type to the argument named type. It doesn’t change the value of the member named type.
But in an initializer list, in an entry like type(type), the first type is the name of the member and the second type is the name of the argument. So the member gets the argument value, and all is well.
You should always use initializer lists in constructors. In addition to allowing duplicate names (if that’s what you like; many programmers don’t) they are more efficient when you have data members with more complex initialization.

Deleting an object from a dynamically allocated array in C++

In the first stage, i've created an object Planet with some attributes, like name, type and distanceToEarth. I've created a Repository then, basically a structure consisting of a dynamic array elems and its length and maximum capacity.
typedef enum {
NEPTUNE_LIKE,
GAS_GIANT,
TERRESTRIAL,
SUPER_EARTH,
UNKNOWN
}PlanetType;
typedef struct {
char name[30];
PlanetType type;
float distanceToEarth;
}Planet;
Planet createPlanet(char name[], PlanetType type, double distance) {
Planet pl;
strcpy(pl.name, name);
pl.distanceToEarth = distance;
pl.type = type;
return pl;
}
typedef struct
{
Planet* elems; /** dynamic array containing the planets */
int length; /** actual length of the array */
int capacity; /** maximum capacity of the array */
} PlanetRepo;
PlanetRepo createPlanetRepo(int capacity) {
/// create a new planet repo; the elems field must be dynamically allocated (malloc)
PlanetRepo r;
r.capacity = capacity;
r.length = 0;
r.elems = (Planet*) malloc(sizeof(Planet)*capacity);
return r;
}
bool remove(PlanetRepo* repo, Planet pl) {
/// #todo remove planet pl from the repository
/// return false if the planet does not exist in the repository
return false;
}
My problem is related to the function remove(). I can't figure out how I am supposed to remove that object from a dynamically allocated array.
Of course, this is not the entire code, but I've selected only the relevant parts. If I forgot to include something, let me know.
Since you insisted on tagging C++, rather than C:
In C++ you wouldn't define the PlanetRepo and the associated functions at all. Instead you would simply declare a variable of type
std::vector<Planet>
or maybe depending on the use case (but less likely)
std::list<Planet>
Both of these already have member functions .erase that remove elements from them.
In C++ you also wouldn't write
typedef struct {
char name[30];
PlanetType type;
float distanceToEarth;
}Planet;
but instead
struct Planet {
char name[30];
PlanetType type;
float distanceToEarth;
};
and you would most likely use std::string instead of char[30] as type for name.
Instead of a function Planet createPlanet(char name[], PlanetType type, double distance) you would define a constructor for Planet:
struct Planet {
std::string name;
PlanetType type;
float distanceToEarth;
Planet(std::string name, PlanetType type, double distance)
: name(name), type(type), distance(distance)
{}
};
and probably make the members private.
You also wouldn't define an unscoped enum, but a scoped one instead (since C++11), see Why is enum class preferred over plain enum?.
Since this is rather a C than a C++ program, you could use a linked list which makes it possible for you to delete elements in a dynamically allocated "array".
This might be of interest.
Like mentioned before C++ has implemented data structures so you can easily store your planets. But you can do something like:
bool remove(PlanetRepo* repo, Planet pl) {
PlanetRepo* temp = (PlanetRepo*) malloc(sizeof(Planet)*repo->capacity);
if(!temp){
return false;
}
temp->capacity = repo->capacity;
temp->size = repo->size-1;
for(int i = 0; i < repo->size; ++i){
if(repo[i] != pl){ //This won't work. How to compare Planets is left as an exercise to the reader
temp[i] = repo[i];
}
}
free(repo);
repo = temp;
return true;
}

How to access and store struct members of vector type?

I have a function in a common module(class) which takes a struct reference of vector type:
The structure has an element which is of Vector type.
Please refer following code snippet:
bool getFrameInfo(ABC& abc);
struct ABC {
int numberOfFrames;
std::vector<XYZ> framInfo;
....
}
struct XYZ {
int size;
Position Pos;
...
}
I need to access and store members of struct XYZ in member variables or local variables in my class which calls the function defined in the common module to get frame information.
Please suggest ways to access and store "XYZ" struct members so that I can use them repeatedly in my program to draw a frame.
Example:
bool getFrameInfo(ABC& abc) {
abc.framInfo[0].size = 10;
// more code, where you return something somewhere
}
This will access your vector from abc, then index its first element (I assume it exists), and access the size field of the first struct of your vector. It stores 10 in its size.

Accessing Variables In Struct Array Outside of Scope

I am brand new to SO, and it all looks very helpful.
My code is being used for cryengine, but this seems to be a good all around c++ problem. And lets face it, the official CE forums blow.
The trouble I'm having is accessing the const char* variable of a struct array outside of the scope I'm assigning the variable in.
BuildingManager.h
class CBuildingManager {
public:
struct SBuilding {
const char* name;
};
struct SBuilding buildings[999];
//string buildingName;
const char* buildingList[999];
};
BuildingManager.cpp
void CBuildingManager::LoadBuildingXML() {
int n = -1;
const char *name;
const char *value;
//XML iterator is long and not necessary for example. n++ per iteration.
//it just works
//last part of iterator
for (size_t j = 0; j < tags->getNumAttributes(); j++) {
//Get building name in XML. This works
tags->getAttributeByIndex(j, &name, &value);
//assign building name to name in struct
buildings[n].name = value;
CryLog("%s", buildings[n].name);
buildingList[n] = buildings[n].name;
}
}
}
}
}
void CBuildingManager::LogAction(int x) {
//x modified by input. also works
CryLog("%c", buildingList[x]); //this, however, does not
}
So basically, I can print the building name as a string inside of the iterator, and it prints the whole building name (ie. "House")
But when I call LogAction, the building name will only print as a char, and will only show a single random symbol.
How can I convert the name in the struct to a string or otherwise get it to print as a whole word outside of the iterator?
Please let me know if my question is vague or shaky, and I will do my best to clean it up.
-Moose

Get list of struct all array and detect the name of each array auto and print it

This is my program
struct All_Modules
{
char* Name;
};
All_Modules First_Array[] = { { "hi\n" } };
All_Modules Next_Array[] = { { "hi1\n" } };
All_Modules Other_Array[] = { { "hi2\n" } };
int main()
{
}
Is there way to get list of All_Modules all array name like (First_Array,...) and show print them like this?
My array is : First_Array | and The of This array is : hi
My array is : Next_Array | and The of This array is : hi1
My array is : Other_Array | and The of This array is : hi2
I know we can set each array to print this but I want first system get the list of all array in All_Modules and detect the names and automatic print the Name value... Is it possible?
Yeah, it is possible, but you have to implement it by yourself using static members.
In the constructor of All_Modules append newly created instance to a global (static) list.
struct All_Modules{
char* Name;
All_Modules(){
gModulesList.push_back(this);
};
static void print_all(){
for(... gModulesList ...){
// print gModulesList[i]->Name;
}
};
private:
static std::list<All_Modules*> gModulesList;
};
In order to do that, you would have to enumerate all global variables for those of a certain type, but C++ doesn't offer a way for that (it's called introspection, BTW). There might be some compiler-specific ways to get at that info though, but they won't be portable.