Skip to content

Instantly share code, notes, and snippets.

@jquimera
Forked from barrysteyn/README.md
Created January 25, 2018 23:12
Show Gist options
  • Save jquimera/4197faaeff933af50c3d136c20ecbed1 to your computer and use it in GitHub Desktop.
Save jquimera/4197faaeff933af50c3d136c20ecbed1 to your computer and use it in GitHub Desktop.
C/C++ Examples For Understanding

Introduction

These toy examples are for helping with understanding C/C++. There is an excellent C++ samples site which demonstrates many useful things.

#include <stdio.h>
#include <stdlib.h>
void func(int* b) {
b = (int*)malloc(sizeof(int)); //What is malloc? Why can't I use new? What's the difference
*b = 400;
printf("%d\n", *b); //What will print here
}
int main() {
int* a = 0;
func(a);
printf("%d\n", *a); //Error - but why? Also, is there a memory leak?
}
//This example follows on from example1.c
#include <stdio.h>
#include <stdlib.h>
void func(int **b) {
*b = (int*)malloc(sizeof(int));
**b = 400;
printf("%d\n", **b); //What will print here
}
int main() {
int **a = (int**)malloc(sizeof(int*));
func(a);
printf("%d\n", **a); //Why does this work?
}
//Ahhhh sanity! This example follows from example 1 and example 2.
//Notice how much neater it is
#include <iostream>
using namespace std;
void func(int*& b) {
b = new int;
*b = 400;
}
int main() {
int * a;
func(a);
cout << *a << endl; //Why does this work?
}
//Constructors and destructors without move constructor
#include <iostream>
using namespace std;
class X {
private:
int num;
public:
//Default constructor
X() : num(0) {
cout << "Default Constructor" << endl;
}
//Overloaded constructor
X(const int& val) : num(val) {
cout << "Overloaded Constructor: Setting num to " << val << endl;
}
//Copy constructor
X(const X& lVal) {
this->num = lVal.num;
cout << "Copy Constructor" << endl;
}
//Copy assignment constructor
X& operator=(const X& lVal) {
this->num = lVal.num;
cout << "Copy Assignment Operator"<<endl;
return *this;
}
//Destructor
~X() {
cout << "Destructor"<<endl;
}
};
X doSomething() {
X x(100);
return x;
}
int main() {
cout << "x1:"<<endl;
X x1 = doSomething();
cout << "x2:"<<endl;
X x2;
x2 = doSomething();
}
// Rule of 5 and Move constructor example
// We will use char* here on purpose (instead of say string)
// Also, this example DRYs the code as much as possible. Can you spot where?
#include <iostream>
using namespace std;
class X {
private:
int test;
char* str;
public:
//Default constructor
X() : str(NULL) { cout << "Default Constructor" << endl; }
//Copy constructor
X(const X& lVal) : X(lVal.str) { cout << "Copy Constructor" <<endl; }
//This is the copy assignment operator
X& operator=(const X& lVal) { cout << "Copy assignment operator" << endl; return *this = lVal.str; }
//Destructor
~X() { cout << "Destructor" << endl; if (str) delete[] str; }
//Move constructor
X(X&& rVal) {
cout << "Move constructor" << endl;
this->str = rVal.str; //Shallow copy
rVal.str = NULL; //Important - set to null otherwise rVal destructor will destroy heap
}
//----- Rule Of "5" Ends Here -----//
//Overloaded constructor
X(const char* lVal) : X() {
cout << "Overloaded constructor: X(const char* lVal)" << endl;
*this = lVal;
}
//Assignment operator (Note: This is not the copy assignment operator)
X& operator=(const char* str) {
cout << "Assignment operator overloaded operator=(const char* str) " << str << endl;
if (this->str) delete [] this->str;
this->str = new char(strlen(str));
for(int i=0; str[i]; this->str[i] = str[i], i++); //Deepcopy - done explicitly here as an example to contrast from shallow copy in move constructor
return *this;
}
const char* getStr() const { return this->str; }
};
X retByVal() {
return X("Hello World");
}
int main() {
X x4(retByVal());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment