Struct Initialization Arguments - c++

I have a struct, player, which is as follows:
struct player {
string name;
int rating;
};
I'd like to modify it such that I declare the struct with two arguments:
player(string, int)
it assigns the struct's contents with those values.

you would use the constructor, like so:
struct player {
player(const string& pName, const int& pRating) :
name(pName), rating(pRating) {} // << initialize your members
// in the initialization list
string name;
int rating;
};

Aside from giving your type a constructor, because as-shown it is an aggregate type, you can simply use aggregate initialization:
player p = { "name", 42 };

Although (as has been pointed out), you can simply add a constructor:
struct player() {
string name;
int rating;
player(string Name, int Rating) {
name = Name; rating = Rating;
}
};
Is there some reason you don't want to make it a class?
class player() {
public:
string name;
int rating;
player(string Name, int Rating) {
name = Name; rating = Rating;
}
};

You are allowed to declare a constructor for your player struct:
struct player {
string name;
int rating;
player(string n, int r) :
name(n),
rating(r)
{
}
};
In C++ one of the few differences between classes and structs is that class members default to private, while struct members default to public.

Related

C++ - Unable to inherit from base class | Gives empty values

I guess I am doing something wrong here in the below code. I want to inherit the methods of class Person in class Employee.
#include<bits/stdc++.h>
using namespace std;
class Person{
private:
string name;
int age;
public:
Person(string name, int age){ //Base parameterized constructor
name = name;
age = age;
}
void getName(){
cout<<"Name: "<<name<<endl;
}
void getAge(){
cout<<"Age: "<<age<<endl;
}
};
class Employee: public Person{ //Default inheritance type is private
private:
int employeeID;
public:
Employee(string name, int age, int id) : Person(name, age){ //Derived parameterized constructor
employeeID = id;
}
void getEmployeeDetails(){
getName();
getAge();
cout<<"Employee ID: "<<employeeID<<endl;
}
};
int main(){
Employee* e = new Employee("John", 24, 14298);
e->getEmployeeDetails();
return 0;
}
I am getting the below output:
Name:
Age: 0
Employee ID: 14298
Please let me know what am I missing here. Any help would be appreciated!
The issue is not with inheritance, but with the fact that Person never initializes any of its fields.
This code:
Person(string name, int age){ //Base parameterized constructor
name = name;
age = age;
}
assigns local variable name to itself and same with age, because parameters shadow class member names. Member objects with the same name are never initialized.
Three solutions possible (listed in subjective order in which I prefer them):
Use member initializer list to initialize your members:
Person(string name, int age) : name{name}, age{age}
{
}
Use different names
Person(string providedName, int providedAge)
{
name = providedName;
age = providedAge;
}
Use this to disambiguate objects
Person(string name, int age){ //Base parameterized constructor
this->name = name;
this->age = age;
}
Nothing to do with inheritance, the code would have been wrong anyway.
This
Person(string name, int age){ //Base parameterized constructor
name = name;
age = age;
}
should be this
Person(string n, int a){
name = n;
age = a;
}
Because your constructor parameter declaration names are the same as your member variables, the member variables are hidden and you were just assigning the parameters to themselves.
A better way to write the same code is to use an initialiser list
Person(string name, int age) : name(name), age(age)
}
Initialiser lists have a couple of advantages, one of them is that there's no ambiguity, you can have the parameter names the same as the member variable names. The other (more important) is that in general, initialisation is more efficient than assignment.

Calling superclass function inheritance c++

In my C++ file, when I run it visual studio, my output is not what I thought it was be an I don't know where I messed up. Basically I have a Person and a Student class, and the student class inherits from the Person class, and when the student obj is created, it calls the Person class to initialize common variables.
class Person {
public:
Person() {
}
Person(string _name, int _age) {
name = _name;
age = _age;
}
void say_stuff() {
cout << "I am a person. " << name << age << endl;
}
private:
string name;
int age;
};
class Student : public Person {
public:
Student(string _name, int _age, int _id, string _school) {
Person(_name, _age);
id = _id;
school = _school;
}
private:
string name;
int age;
int id;
string school;
};
int main() {
Student s1("john", 20, 123, "AAAA");
s1.say_stuff();
system("pause");
return 0;
}
My output is I am a person. -858993460
Why is this?
The way you invoke the constructor of the super class is wrong. This is how you should do it:
Student(string _name, int _age, int _id, string _school) : Person(_name, _age) {
id = _id;
school = _school;
}
Note that, When you put Person(_name, _age); inside the body, it has no effect but to construct a temporary Person object. On the other hand, the correct way above references the "embedded" Person to be constructed with these parameters.
Your Student constructor's syntax is wrong, for constructing it's superclass. It should be:
Student(string _name, int _age, int _id, string _school)
: Person(_name, _age) {

Can we call member function only in member initialization list in c++?

I want provide a class with a member function that will initialize the all member of class separately.
e.g.
#include <iostream>
using namespace std;
int x = 10;
class my{
public:
my():init{}
int &i;
void init()
{
i = x;
}
};
int main()
{
my m;
return 0;
}
I know if I can use "class my : i(init())" will work, but I have some special purpose to intialize like above.
However in above example, I'm getting following error:
class ‘my’ does not have any field named ‘initMy’.
How to resolve this?
If you are trying to write a constructor for class my, then it must be named with the class name. The following will work assuming that initMy is the name of another class that you are trying to subclass.
class my : initMy
{
public:
int i;
my() {
i = 10;
}
};
You might try to pre-initialize all the fields, then calling the initializing function inside the constructor:
class my {
public:
int i;
void initMy() {
i = 10;
}
my() : i(0) { initMy(); };
};
You could also (in C++11) define a bizarre signature for a private constructor, and delegate a constructor to it
class my {
private:
void initMy () { i=10; };
enum privateen {privatev};
my(enum privateen) : i(0) { initMy(); };
public:
my() : my(privatev) {};
int i;
};
Actually, I believe that your initialization should be in a constructor, not in some other function.
Few things to clarify here.
Member initialization list is for initialize members (mostly same purpose of the constructor).In initialize list nothing to do with member functions. in this example age(newAge) is not a function. It is initializing age variable.
class Man{
private:
int age;
string name;
public:
Man(int newAge):age(newAge),name("Jhon"){}
};`
You can use constructor to initialize the members of the class.
class Man{
private:
int age;
string name;
public:
Man(int newAge)
{
age = newAge;
name = "Jhone";
}
};
Alternatively you can use a init method to do initialization, if you have some issue to use constructor.
class Man{
private:
int age;
string name;
public:
Man(){}
init(int newAge, string newName)
{
age = newAge;
name = newName;
}
};
If you need to set the value of only one member in a class, you have to use a setter method
class Man{
private:
int age;
string name;
public:
Man(){}
setAge(newAge)
{
age = newAge;
}
setName(newName)
{
name = newNAme
}
};
edit:
class Man{
private:
int age;
string name;
public:
Man(initAge, initName)
{
setValues(initAge, initName);
}
setValues(newAge, newName)
{
age = newAge;
name = newName;
}
};
int main()
{
Man goodMan(34,"Jhon");
goodMan.setValues(45,"Kevin");
}

Can we initialize structure memebers through smart pointer in initialization list?

#include <boost/scoped_ptr.hpp>
class classA
{
protected:
struct StructB
{
int iAge;
double dPrice;
};
boost::scoped_ptr<StructB> m_scpStructB;
public:
classA(int age, double price)
: m_scpStructB(new StructB)
{
m_scpStructB->iAge = age;
m_scpStructB->dPrice = price;
}
/* DO NOT COMPILE <= second block
classA(int age, double price)
: m_scpStructB(new StructB),
m_scpStructB->iAge(age),
m_scpStructB->dPrice(price)
{}
*/
};
Question1> I have found that I cannot use the second block of code to initialize structure members pointed by a smart pointer. Is it a general c++ rule that we just cannot do it.
Please discard this question if the answer to the first question is "You cannot do it".
Question2> As far as I know, the order of assignment on initialization list is based on the order of member variables definition. Assume that you can initialize the member variables through smart pointer. How can you guarantee the order so that the smart point is initialized always first?
If you don't need StructB to be an aggregate/POD type, then just give it a constructor too:
#include <boost/scoped_ptr.hpp>
class classA
{
protected:
struct StructB
{
StructB(int age, double price) : iAge(age), dPrice(price) { }
int iAge;
double dPrice;
};
boost::scoped_ptr<StructB> m_scpStructB;
public:
classA(int age, double price) : m_scpStructB(new StructB(age, price)) { }
};
Otherwise you can just use a factory function, so that it remains a POD type:
#include <boost/scoped_ptr.hpp>
class classA
{
protected:
struct StructB
{
int iAge;
double dPrice;
static StructB* make(int age, double price)
{
StructB* ret = new StructB;
ret->iAge = age;
ret->dPrice = price;
return ret;
}
};
boost::scoped_ptr<StructB> m_scpStructB;
public:
classA(int age, double price) : m_scpStructB(StructB::make(age, price)) { }
};

default init value for struct member of a class

The fragment below is from a VC++ 2008 Express Edition.
Say, I have a class with a member that is a struct. I am trying to define default values for the member variables of this class. Why this does not work?
struct Country{
unsigned chart id;
unsigned int initials;
std::string name;
};
class world{
private:
Country _country;
unsigned int _population;
public:
world(){};
world():
_country():
id('1'), initials(0), name("Spain") {};
_population(543000) {}
:
:
~world(){};
};
There are two ways to initialize the country member data. Like this ...
struct Country{
unsigned char id;
unsigned int initials;
std::string name;
};
class world{
private:
Country _country;
public:
world()
{
_country.id = '1';
_country.initials = 0;
_country.name = "Spain";
}
~world(){};
};
... or, like this ...
struct Country{
unsigned char _id;
unsigned int _initials;
std::string _name;
Country(
unsigned char id,
unsigned int initials,
const std::string& name
)
: _id(id)
, _initials(initials)
, _name(name)
{}
};
class world{
private:
Country _country;
public:
world()
: _country('1', 0, "Spain")
{
}
~world(){};
};
Note that in the second example I find it easier to initialize the Country instance because I defined a constructor as a member of the Country struct.
Or, perhaps you want to give the Country type a default constructor:
struct Country{
unsigned char _id;
unsigned int _initials;
std::string _name;
Country()
: _id('1')
, _initials(0)
, _name("Spain")
{}
};
class world{
private:
Country _country;
public:
world()
{
}
~world(){};
};
The structure is an aggregate type.
Since it has no constructor you cannot initialise it with normal brackets, you can however use curly braces as you would initialise an array.