Class, Struct and Constructor
Must Know Prerequisites
->
'arrow operator' :
->
arrow operator is member selection from pointer operator
If we want a value of a member variable from a struct
using a pointer
, then we must use ->
arrow operator as shown below ↴
ptr->x
is same as(*ptr).memberVariable
StructName *ptr = &obj1;
cerr << (*ptr).varName << endl;
cerr << ptr->varName << endl;
Another example
struct Paw
{
int claws;
};
struct Animal
{
string name;
Paw paw; // ⚠ `paw` is of type struct `Paw`
};
int main()
{
Animal puma {"Puma", {5}};
Animal *ptr {&puma};
cout << (ptr->paw).claws << '\n';
cerr << (*ptr).paw.claws << endl; // same as obove just bit complicated to look at
cout << ptr->name << '\n';
cerr << (*ptr).name << endl; // same as obove just bit complicated to look at
}
struct
struct st
{
int a;
double b;
string x;
};
int main()
{
st hell{45, 89.0, "9"}; // prefer this✅
/* this type of initialisation is called "Initialization list" */
st hell = {45, 89.0, "9"}; // also OK
cout << hell.a << hell.b << hell.x << endl;
}
using one struct
inside another struct
#include <iostream>
struct Employee
{
int id {};
int age {};
double wage {};
};
struct Company
{
int numberOfEmployees {};
Employee CEO {}; // Employee is a struct within the Company struct
};
int main()
{
Company myCompany{ 7, { 1, 32, 55000.0 } }; // Nested initialization list to initialize Employee
std::cout << myCompany.CEO.wage; // print the CEO's wage
}
nested structs: declaring struct inside another struct
#include <iostream>
struct Company
{
struct Employee // accessed via Company::Employee
{
int id{};
int age{};
double wage{};
};
int numberOfEmployees{};
Employee CEO{}; // Employee is a struct within the Company struct
};
int main()
{
Company myCompany{ 7, { 1, 32, 55000.0 } }; // Nested initialization list to initialize Employee
std::cout << myCompany.CEO.wage; // print the CEO's wage
}
Constructor
when we see something like this: These are Constructors as discussed in below section.
Hint: only
:
without?
means these are constructors
class class_a {
public:
class_a() {}
class_a(string str) : m_string{ str } {}
class_a(string str, double dbl) : m_string{ str }, m_double{ dbl } {}
double m_double;
string m_string;
};
Declare Constructors
Short way of declaring Constructor (used in Leetcode)
Foramt:
StructName(/* Parameters or No Paramters*/) : variable(valueOfvariable) {}
StructName(/* Parameters or No Paramters*/) : variable{valueOfvariable} {}
// `{ }` curly braces are also allowed
- NOTE:
- no semi-colon
;
after the{}
at the end of line - use brace initialization i.e.
vareName{ _valueGiven_ }
or direct initialisationvarName( _valueGiven_ )
: both are right -- Leetcode usesvarName(..)
- no semi-colon
// Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
common way of declaring Constructor
struct StructExample
{
int a;
double b;
string x;
StructExample()
{
a = 78;
b = 89.889;
x = "Common way of declaring Constructor";
}
};
Default Constructor
struct StructExample
{
int a;
double b;
string x;
StructExample() : a(78), b(89.889), x("Constructor"){} /* here a(78) is called '"brace initialization"' */
};
struct StructExample
{
int a;
double b;
string x;
// StructExample() : a(78), b(89.889), x("Constructor"){}; /* ALTERNATIVE to this is below common way*/
StructExample()
{
a = 78;
b = 89.889;
x = "Brace Constructor";
}
};
If you have constructors in your class and need a default constructor that does nothing (e.g. because all your members are initialized using non-static member initialization), use
StructName() = default
Another smart way of Default Constrcutor
class StructName
{
public:
// Default constructor
StructName(int n = 0, double d = 1.2) // allows us to construct a StructName(int, double), StructName(int), or StructName()
{
}
};
int main()
{
StructName s1 { 1, 2.4 }; // calls StructName(int, double)
StructName s2 { 1 }; // calls StructName(int, double)
StructName s3 {}; // calls StructName(int, double)
StructName s4 { 2.4 }; // will not compile, as there's no constructor to handle StructName(double)
return 0;
}
Parameter Constructor
// Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
List initialization vs Direct initialization
List initialisation varName{..}
or Brace Initialisation
- always use List Initialization
variableName{ _valueGiven_ }
for giving vlaues to the variables - always use use List Initialization for giving values to tuples, maps, pairs and some other data structures
- Only use Direct Initialisation when giving values to variables inside a Constructor
List initialisation
TO LEARN FROM learncpp.com
So how do we use this constructor with parameters? It's simple! We can use list or direct initialization:
Fraction fiveThirds{ 5, 3 }; // List initialization, calls Fraction(int, int)
Fraction threeQuarters(3, 4); // Direct initialization, also calls Fraction(int, int)
As always, we prefer list initialization. We'll discover reasons (
templates
andstd::initializer_list
) to use direct initialization when calling constructors later in the tutorials. There is another special constructor that might make brace initialization do StructName different, in that case we have to use direct initialization. We'll talk about these constructors later.