Calling a struct in a class from main in C++ - c++

I have a header file with a class and a struct in it, but I can't figure out how to call it from main.
class TestDetails {
public:
struct User{
std::string username;
std::string password;
};
};
How do I call the following from main,and store a struct into a vector so I can
pass into a text file?

If by "calling a struct" you mean instantiating it, then knowing that the type is TestDetails::User, you simply need to create a vector<TestDetails::User>. Then you can fill it up with objects like you would do with any other type. For example,
// instantiate a vector with two users
std::vector<TestDetails::User> v{{"bob", "1234"},
{"alice", "alice_psswd"}};
// add another user
v.push_back({"trudy", "****"});

Related

Error trying to create map outside of main function. C++

I'm very new to C++ but I am trying to create a map and insert values into it from a class but seem to keep getting an error.
class Album {
public:
map<string,string> albums;
albums.insert(make_pair("rap","Kamikaze")); // This gives the error
};
when i put those same two lines inside the main function, it works without an issue. Like I said I'm very new to C++ so please don't roast me if it's something simple.
(Also, I have map included and using namespace std added)
You are trying to run code in a space where code isn't supposed to be. You can instead write
class Album {
public:
map<string,string> albums;
Album() {
albums.insert(make_pair("rap","Kamikaze"));
}
};
This will run the code every time the class is instantiated, effectively making it the default value for albums.
Class is not a function. Class body can only contain declarations. Executable code may only be in functions (including class methods). For example:
class Album {
public:
map<string,string> albums;
void add_album(string a, string b) {
albums.insert(make_pair(a, b));
// or: albums.emplace(a, b); // if supported
}
};
...
int main() {
...
Album my_album;
my_album.add_album("rap", "Kamikaze");
my_album.albums.insert(make_pair("some", "Thing"));
...
}
No problem its very simple. Below here is a class definition and map that you have declared is its public data member.
Now this Class will act as a prototype for all "Album" objects and all object created will have their own map member.
class Album {
public:
map<string,string> albums;
};
Consider below example,
Album objA; //Object of Album class is created here
//Map being a public member can directly be accessed here
ObjA.albums.insert(make_pair("some", "Thing"));
So instead of calling insert function in class definition you need to do it this way.
Similarly for objectB,
ObjB.albums.insert(make_pair("some", "Thing"));

Streamlining Parameter Passing

I am reading through Code Complete and had a question about "Streamlining parameter passing". The author says that if you are passing a parameter among several routines, that might indicate a need to factor those routines into a class that share the parameter as class data.
Does this mean that if I have several separate class that use the same data I should create one new class that uses that data and then inherit to make new classes?
Or
Does this mean that if I have a bunch of loose routines in my program I should go ahead and put them into a class and get the benefits of encapsulation, etc.
The latter. It looks like they're talking about a case like this:
void function_1(std::string& my_data);
void function_2(std::string& my_data);
void main() {
std::string my_data = "SomeString";
function_1(my_data);
function_2(my_data);
}
Which could be changed to:
class MyClass {
std::string my_data;
public:
MyClass(const std::string& str) : my_data(str) {}
void function_1();
void function_2();
}
void main() {
MyClass obj("SomeString");
obj.function_1();
obj.function_2();
}
Where function_1 and function_2 use the my_data field, instead of having to be passed the string every time.

C++ struct with template in vector

I'm making a text adventure game in C++. This is the struct for an object in that game (something the user can pick up and put in the inventory)
template <int N>
struct Object
{
static const int length = N;
string names[N];
string description;
};
Examples of objects:
Object<2> flower = { {"flower", "the flower"}, "A strange looking flower"};
Object<3> book = { { "the book", "book", "recipe book" }, "The world's finest cocktail recipes now all in one easy to use companion." };
The multiple names are synonyms for the command parser, so the user can input "pick up book" or "pick up recipe book", which in both cases picks up the object book.
Now I'd like to create a vector inventory to store all the elements in the inventory.
vector<Object> inventory;
Now, off course, this gives me a compiler error, because it expects something like this:
vector<Object<5>> inventory;
However, some objects have more names than others, is something like this possible and if so, how?
vector<Object<N>> inventory;
All your different Object<N> classes are different types with different sizes. You can't put them in a homogenous container.
You would need some base class or base interface, and store pointers in the vector, relying on virtual dispatch and polymorphism when you pull the elements out. This would make your container of Objects a heterogenous container.
Alternatively, and preferably, drop the template and store the names in a member container:
struct Object
{
set<string> names;
string description;
};
vector<Object> easy;
PS. I don't consider Object to be a good name for any class. CompuChip's suggestion of InventoryItem makes more sense.
A vector needs to know the size of the objects it contains, so obviously it cannot allow varying template instances inside (sizeof(Object<N+X>) > sizeof(Object<N>)).
Remove the templated array from the main Object struct, and replace it with a common vector or list or string objects instead, and your problem is solved.
Derive Object from BaseObject, and form a vector of smart pointers to BaseObject:
struct BaseObject
{
virtual ~BaseObject() = default;
};
template<int N>
struct Object : public BaseObject
{
static const int length = N;
string names[N];
string description;
};
typedef shared_ptr<BaseObject> Objptr;
vector<Objptr> Inventory(1006);

Forward declaration in externing data from DLL to core program

I'm writing a dll, which contains a c++ class definition, and a core program based on the proxy pattern, as described in this tutorial: http://www.linuxjournal.com/article/3687
Specifically, this dll, after is loaded on the core program, will fill its definition including the class's name, method's name, and method's function pointer in the data structure of the core program.
However, I want to modify this pattern for the different kinds of classes, instead of only one base kind in the article, which is the reason why I use the function pointer.
My program is as following:
//the base class
class common_object{
};
//this factory is used for storing constructor for each c++ class in the dll.
typedef common_object *maker_t();
extern map< string, maker_t* > factory;
//store all the methods of a class
//string: method's name
typedef map<string, proxy::method> method_map;
//string: class's name
extern map<string, method_map> class_map_;
// our global factory
template<typename T>
class proxy {
public:
typedef int (T::*mfp)(lua_State *L);
typedef struct {
const char *class_name;
const char *method_name;
mfp mfunc;
} method;
proxy() {
std::cout << "circle proxy" << endl;
// fill method table with methods from class T
// initialize method information for the circle class
method_map method_map_;
for (method *m = T::methods;m->method_name; m++) {
/* edited by Snaily: shouldn't it be const RegType *l ... ? */
method m1;
m1.class_name = T::className;
m1.method_name = m->method_name;
m1.mfunc = m->mfunc;
method_map_[m1.method_name] = m1;
}
//register the circle class' description
class_map_[T::class_name] = method_map_;
}
};
In this program, I extern two data structs of the core problem:
class_map: contain all the class in the dll loaded in the core
program. method_map:
method_map: contains all the methods'description for each
class.
the relation between class_map and method is one-to-many.
However, I run into a problem of declaration order of class_map_ and method_map. Specifically, I extern class_map outside the class Proxy, but I also have to define the method structure inside this class.
I tried to use forward declaration in the following link: When can I use a forward declaration?, but it doesn't work.
I hope to see your solution about my problem. Thanks so much

C++ : Using an array in a nested class definition (OOP)

So I am trying to define a class and I am using another array of a different class to define it.
//header file for Name.h
class Name {
string last;
string first;
};
//header file for Depositor.h
class Depositor {
Name name;
string ssn;};
//header file for Account.h
class Account {
Depositor depositor;
int acctnum;
string type;
double balance;
};
//header file for Bank.h
#include "Account.h"
class Bank {
Account account[]; //is this possible?
int active_accts;
};
When I am writing the cpp file I am running into a lot of problems!
//example of mutator
void Bank::setLastname(string lastname)
{
account.setLastname (lastname);
}
I didn't include the mutators and acessors that I wrote into the header file, but they are there and are public -- it won't compile.
Can you help? Is it even valid to use an array of a class in Bank.h?
Is it even valid to use an array of a class in Bank.h?
Yes, but it has to have a fixed dimension, e.g.,
Account account[3];
A type always has a fixed size in C++, and since an array member variable forms part of the class's size, you need to specify how many elements are in the array.
If you don't know how many elements you are going to need, you can use a sequence container:
std::vector<Account> account;
Account is not a nested class of Bank. Bank has a member data instance of type Account array.
You can have a primitive array member in a class, but you must specify the size of the array in the class definition: Account account[42];. The reason is that when you #include the class definition in another compilation unit, and then instantiate an instance of the class, the compiler needs to know what the size of that instance is.
It would be a wise idea to use std::vector<Account> rather than a primitive array. std::vector doesn't require committing to a particular size at construction; it grows dynamically. How come a std::vector doesn't require a size in the class definition, while a primitive array does? A std::vector holds as member a pointer to the elements on the heap. So the compiler does know the size of a std::vector; it uses the size of the pointer rather than the count of the elements.
By declaring the value of the array in the header file and by adding a variable in the .cpp file you can solve all the problems and leave it as an array.
//header file
class Bank {
Account account[100];
int active_accts;
public:
//mutator
void setLastname (string,int);
};
//the implementation file
void Bank::setLastname (string last, int index)
{
account[index].setLastname(last);
}
this will solve all your problems
account is an array of Accounts, which means you would need to do something like account[0].setLastname(lastname);
Instead of arrays, consider using vectors.
#include <vector>
// ...
class Bank {
std::vector<Account> accounts;
int active_accts;
};
you can't call setLastname(lastname) on the whole array. You need to call it on a specific instance of the Account class inside the array, like this: account[0].setLastname(lastname);
On another note, you really should be storing an array of pointers to Account objects.