New blog location
New blog location
reset
, the reference count is decremented. When the reference count goes to 0, the data pointed to is deallocated. Use make_shared
:auto person = std::make_shared<Person>(); if(person) { cout << "Person's address is " << person->address; }
make_shared
cannot be used. Below is an example:shared_ptr<Person[]> persons(new Person[10]); persons[0]._name = "Jack Sparrow"; persons[0]._address = "Caribbean"; cout << "Address of first person "<<persons[0].address << endl;
std::vector
as it can dynamically grow and shrink.std::vector<std::shared_ptr<Person>> persons; auto person1 = std::make_shared<Person>("Jack Sparrow","Caribbean"); auto person2 = std::make_shared<Person>("Hector Barbossa","Bahamas"); persons.push_back(person1); persons.push_back(person2); for (auto& person : persons) { std::cout << "Person name is " << person->_name << " and address is " << person->_address << "\n"; }
const
is in declaring and defining values that are initialized once and cannot change. These replace the #define
macro constants from C. Examples:const double PI = 3.14; const int NUMVALUES = 42; const std::string quote = "To be or not to be";
const
can be used is in making sure parameters cannot be modified. For example, if a function takes an int*
pointer, passing the pointer with const
ensures the function cannot change the value. Example:int main() { int num = 5; int *val = # foo(val); } void foo(const int* value) { *value = 6; //will fail to compile }
double aDouble = 3.14 double& refToDouble = aDouble;
refToDouble = 6.0; cout << "Double value is " << aDouble << endl; //prints out 6.0
int main() { int x = 5; int y = 3; swap(&x, &y); printf("x is %d and y is %d",x,y); //prints out 3 and 5 } void swap(int *a , int *b) { int temp; temp = *a; *a = *b; *b = temp; }
int main() { int a = 2; int b = 3; swap(a,b); } void swap(int &a , int &b) { int temp; temp = a; a = b; b = temp; }
const
Referenceconst
reference. Example:void foo(const int& a) { int b = a * 2; a++; //compiler will throw an error here as one attempts to modify a. }
std::string
by const
reference, passing in string literals works.auto
and decltype
are used in C++ for type inference. auto
is used as follows:auto x = 2 + 3;
auto
becomes apparent when dealing with complex types returned by a function. Note that using auto
strips away reference and const reference qualifiers and makes copies, so if a function is returning a reference, be sure to use auto&
. Similarly use const auto&
for const
reference.int& bar() { int* dynInt = new int; *dynInt = 5; return *dynInt; } auto retVal = bar(); //A copy is made here. Use auto& instead.
decltype
takes an expression as an argument and infers the type of that expression. The advantage is that reference and const references are not stripped out. Example:decltype(bar()) retVal = bar();
checkingaccount.h
:#ifndef BANKACCOUNT_H #define BANKACCOUNT_H #include <string> using std::string; class CheckingAccount { public: CheckingAccount(string accountHolder, string accountNumber, double balance); double getBalance() const; string getAccountHolder() const; string getAccountNumber() const; void deposit(double amount); string withdraw(double amount); ~CheckingAccount(); private: string mAccountHolder; string mAccountNumber; double mBalance; } #endif
checkingaccount.cpp
:#include "checkingaccount.h" CheckingAccount::CheckingAccount(string accountHolder, string accountNumber, double balance) { mAccountHolder = accountHolder; mAccountNumber = accountNumber; mBalance = balance; } double CheckingAccount::getBalance() const { return mBalance; } string CheckingAccount::getAccountHolder() const { return mAccountHolder; } string CheckingAccount::getAccountNumber() const { return mAccountNumber; } void CheckingAccount::deposit(double amount) { mBalance += amount; } string CheckingAccount::withdraw(double amount) { if(mBalance - amount <= 0.0) { return "Insufficient Funds"; } mBalance -= amount; return "Amount withdrawn successfully"; } CheckingAccount::~CheckingAccount() { //no cleanup for this case }
delete
is called on a heap-allocated object. The constructor is responsible for initializing the class whereas the destructor is responsible for cleanup, include closing file handles, freeing up memory allocated by the object, and so on. It is the function marked with the ~
.CheckingAccount::CheckingAccount(string accountHolder, long accountNumber, double balance) :mAccountHolder(accountHolder), mAccountNumber(accountNumber), mBalance(balance) { }
#include "checkingaccount.h" #include <memory> using std::unique_ptr; using std::cout; using std::endl; int main() { CheckingAccount chkAcnt("Jack Sparrow","61723",10000); //allocated on the stack. chkAcnt.deposit(100.0); chkAcnt.withdraw(50.0); auto chkAccntTwo = make_unique<CheckingAccount>("Hector Barbossa",61724,10000); chkAccntTwo->deposit(1000.00); chkAccntTwo->withdraw(5000.00); cout << chkAccountTwo.getAccountHolder() <<"'s balance is "<< chkAccntTwo->getBalance() << endl; } //chkAcnt destructor is called here. chkAccntTwo destructor also called here as unique_ptr goes out of scope.
Comments
Post a Comment