under construction

C++ Syntax

[Based on C Systax]
[New Type Modifiers]
[New Function Declarations]
[Exceptions]
[Classes]
[Derived Classes]
[Special Member Functions]
[Dynamic Memory]
[Templates]
[Standard IO]
other languages..


New Type Modifiers

//////////////////////////////////////////////////////////////////////////////
//  name: new_type_modifiers
//  purpose: show the new type modifiers
//  args: (out) result - ref of the result of this func
//        (in)  array - input array of 5 real numbers
//  returns: a ref to a real number
//  notes: passing large args by ref reduces copying without changing code
//////////////////////////////////////////////////////////////////////////////
float &new_type_modifiers(int &result, float array[5])
{
  // references               // reduces lengthy usage of ptrs and *
  int number = 0;
  int &same_number = number;  // same_number is number
  same_number++;              // number now equals to 1
  char ch = 'a';              // can declare vars anywhere
  char *ch_ptr = &ch;         // this is c style
  char &ch_ref = ch;          // this is cpp style
  ch_ref = ch_ref + 1;        // no need to write *ch_ptr everywhere
  
  // consts                   // replace usage of #defines
  const double pi = 3.14;     // pi cannot be changed anymore
  int private_member = 0;     // we dont want anyone to change it but us
  const int *ptr_private = &private_member; // allows read only access
  *ptr_private = -1;          // ILLEGAL
  int *const number_ptr = &number;          // ptr itself is const
  number_ptr = NULL;          // ILLEGAL
  
  // bool
  bool is_ok = TRUE;          // bool is actually int, TRUE = 1, FALSE = 0
  
  // a bit more references
  result = 42;                // no need to pass ptrs, forget *result = 42
  return array[2];            // we can write: new_type_modifiers(i,a) = 0.22;
}

New Function Declarations

//////////////////////////////////////////////////////////////////////////////
//  name: inline_free
//  purpose: reduce function call overhead in cost of larger code (duplication)
//  args: (in)  ptr - ptr to free
//  returns: nothing
//  notes: replaces usage of #define macros
//////////////////////////////////////////////////////////////////////////////
inline void inline_free(void *ptr)
{
  if (ptr != NULL) free(ptr);
}

//////////////////////////////////////////////////////////////////////////////
//  name: sqrt
//  purpose: overload a function, same name, different param types / numbers
//  args: (in)  number - number to calculate square root of
//  returns: the square root of number
//  notes: makes names clearer, no need for sqrt_int and sqrt_float
//          especially useful when only one name permitted, such as ctors
//////////////////////////////////////////////////////////////////////////////
float sqrt(int number);
float sqrt(float number);

//////////////////////////////////////////////////////////////////////////////
//  name: default_params
//  purpose: show that some arguments can be optional
//  args: (in)  num - number to do something to
//        (in)  debug - should debug info be printed or not
//  returns: nothing
//////////////////////////////////////////////////////////////////////////////
void default_params(int num, bool debug = FALSE);

Exceptions

//////////////////////////////////////////////////////////////////////////////
//  name: Exception
//  purpose: implement a very simple exception class
//////////////////////////////////////////////////////////////////////////////
class Exception {};

//////////////////////////////////////////////////////////////////////////////
//  name: show_exceptions
//  purpose: show usage of c++ exceptions (not SEH)
//  args: none
//  returns: nothing
//  notes: exceptions cause a size and speed overhead, use scarcely
//////////////////////////////////////////////////////////////////////////////
void throw() show_exceptions() // throw() is optional, means func doesnt throw
{
  // regular c++ exceptions //////////////////////////////////////////////////
  try
  {
    int res = return_zero_on_success();
    if (1 == res) throw "operation failed with code 1"; // indicate a problem
    if (2 == res) throw Exception();
  }
  catch (char *str)       // handle only char* exceptions
  {
    log_exception(str);   // do something with the string thrown
    throw;                // re-throw current exception
  }
  catch (Exception &e)    // several catches allowed
  {
    log_exception("Exception class thrown");
  }
  catch (...)             // handle all exceptions
  {
    return;
  }

  // MS-specific Structured Exception Handling (SEH) is integrated into c++
  // syntax is similar with __try, __except, __finally blocks
  // used mainly to catch OS / hardware exceptions such as access violations
  // not used nicely for logical flow control (throws with RaiseException(code))
}

Classes

//////////////////////////////////////////////////////////////////////////////
//  name: Vector
//  purpose: implement a class of a simple vector
//  notes: default access is private in classes, in structs its public
//////////////////////////////////////////////////////////////////////////////
class Vector
{
private:        // these are members only accessible from this class
  static int num_created; // this var will exist regardlesss of instances
protected:      // these are members accessible by this and derived classes
  float _x, _y;
public:         // these are members accessible by all
  Vector();                           // default ctor
  Vector(float x, float y);           // overloaded ctor
  float GetSize();                    // method
  static int GetNumCreated();         // will exist regardless of instances
};
// default ctor implementation
Vector::Vector()
{
    _x = _y = 0;
    num_created++;  // access may have to be synchronized if multi-threaded
}
// overloaded ctor implementation
Vector::Vector(float x, float y)
{
    this->_x = x;   // usage through this is also ok (but not in static)
    this->_y = y;
    num_created++;  // access may have to be synchronized if multi-threaded
}
// Size method implementation
float Vector::GetSize()
{
    return sqrt(_x*_x+_y*_y);
}
// static member initialization
int Vector::num_created = 0;
// static method implementation
int Vector::GetNumCreated()
{
  return num_created;
}

////////////////////////////////// usage /////////////////////////////////////
int total_num = Vector::GetNumCreated();
Vector vec1;
Vector vec2(0.23,0.98);
float vec2_size = vec2.GetSize();

Derived Classes

//////////////////////////////////////////////////////////////////////////////
//  name: Object
//  purpose: implement an abstract class of a simple object
//  notes: you can't make instances of an abstract class
//////////////////////////////////////////////////////////////////////////////
class Object
{
  float _weight;                  // default access is private in classes
  Object() {}                     // default ctor cannot be called - private
public:                           // these are members accessible by all
  Object(float weight)            // cannot be virtual, will be called first
  {
    _weight = weight;             // can also be implemented here
  }
  virtual ~Object() {}            // base ptr call will call the derived method
  float GetWeight();              // base ptr call will call the base method
  virtual void PrintName() = 0;   // = 0, must be implemented in derived
};
// implementation of non virtual GetWeight
float Object::GetWeight()
{
    return _weight;
}

//////////////////////////////////////////////////////////////////////////////
//  name: Soap
//  purpose: implement a simple derived class (throwable branded soap)
//  notes: only ctors and dtors are called in chains (overriden methods aren't)
//////////////////////////////////////////////////////////////////////////////
class Soap : public Object        // Soap is derived from Object, multiple ok
{
  char *_brand;
  Vector _speed;
public:
  Soap(char *brand, float weight = 1.33)  // will be called second
    : Object(weight), _speed(0,0)         // initializer list of object ctors
  {
    _brand = new char[strlen(brand) + 1];
    strcpy(_brand, brand);
  }
  virtual ~Soap()                         // will be called first
  {
    delete[] _brand;                      // cleanup after ctor
  }
  virtual void PrintName();               // we must implement this method
};
// implementation of pure virtual PrintName
virtual void Soap::PrintName()
{
  cout << "Soap produced by " << _brand << endl;
}

////////////////////////////////// usage /////////////////////////////////////
Soap my_soap("Gillette");
float wight = my_soap.GetWeight();  // calls Object implementation
Object *my_obj = &my_soap;
my_obj->PrintName();                // calls Soap implementation (polymorphism)

Special Member Functions

//////////////////////////////////////////////////////////////////////////////
//  name: String
//  purpose: implement a simple string to show special member funcs
//////////////////////////////////////////////////////////////////////////////
class String
{
  char *_data;
  void ReplaceData(char *data);
public:
  String(char *data = NULL);  // default ctor (with default params)
  virtual ~String();          // dtor, good habit to always make dtor virtual
  String(int number);         // conversion ctor (from int)
  String(const String &str);  // copy ctor
  String &operator=(String &str);   // overloaded assignment
  String operator+(String &str);    // overloaded addition
};
// private func to assist us
void String::ReplaceData(char *data) {
  if (_data != NULL) delete[] _data;
  _data = NULL;
  if (data != NULL)
  {
    _data = new char[strlen(data) + 1];
    strcpy(_data, data);
  }
}
// default ctor implementation
String::String(char *data) {
  _data = NULL;
  ReplaceData(data);
}
// dtor implementation
virtual String::~String() {
  ReplaceData(NULL);
}
// conversion ctor (from int) implementation
String::String(int number) {
  _data = new char[32];
  sprintf(_data, "%d", number);
}
// copy ctor implementation
String::String(const String &str) {
  _data = NULL;
  ReplaceData(str._data);
}
// overloaded assignment implementation
String &String::operator=(String &str) {
  ReplaceData(str._data);
  return *this;     // returns left hand side for str1=str2=str3
}
// overloaded addition implementation
String String::operator+(String &str) {
  int united_len = 1;
  if (_data != NULL) united_len += strlen(_data);
  if (str._data != NULL) united_len += strlen(str._data);
  char *united = new char[united_len];
  united[0] = 0x00;
  if (_data != NULL) strcat(united, _data);
  if (str._data != NULL) strcat(united, str._data);
  String res(united);
  delete[] united;
  return res;
}

////////////////////////////////// usage /////////////////////////////////////
String bh("BeverlyHills");    // default ctor with param
String zp = 90201;            // conversion ctor (from int)
String bh2 = bh;              // copy ctor
String zp2;                   // default ctor no param
zp2 = zp;                     // assignment
cout << bh + zp << endl;      // addition

Dynamic Memory

#include <new>

//////////////////////////////////////////////////////////////////////////////
//  name: show_allocation
//  purpose: show usage of new and delete operators
//  args: (in)  elements - number of elements to allocate
//  returns: 0 on success, -1 on failure
//////////////////////////////////////////////////////////////////////////////
int show_dynamic_mem(int elements)
{
  // vars
  int ret = 0;

  // regular c++ new throws exception on problem /////////////////////////////
  Vector *ptr_vec = NULL;
  int *int_arr = NULL;
  try
  {
    ptr_vec = new Vector(1.1,3.6);
    int_arr = new int[elements];
    // do something with our buffers
  }
  catch (std::bad_alloc &e)
  {
    ret = -1;
  }
  delete ptr_vec;     // cleanup, ok to delete a NULL pointer
  delete[] int_arr;   // use delete[] when allocating arrays
  
  // altered c++ new returns NULL on problem /////////////////////////////////
  char *buffer = new(std::nothrow) char[elements];
  if (buffer != NULL)
  {
    // do something with our buffer
  }
  else ret = -1;
  delete[] buffer;    // cleanup

  return ret;
}

Templates

//////////////////////////////////////////////////////////////////////////////
//  name: template_min
//  purpose: show usage of a template function (find minimum)
//  args: (in)  first - first object to compare (unknown type - T1)
//        (in)  second - second object to compare (unknown type - T1)
//  returns: the smaller one, as an unknown type - T2
//  notes: T1 must implement <, T1 must be castable to T2
//          this removes need to rewrite the func many times with diff types
//////////////////////////////////////////////////////////////////////////////
template <class T1,class T2> T2 template_min(T1 first, T1 second)
{
  if (first < second) return (T2)first;
  else return (T2)second;
}

//////////////////////////////////////////////////////////////////////////////
//  name: Stack
//  purpose: show usage of a template class (stack of max SIZE Ts)
//////////////////////////////////////////////////////////////////////////////
template <class T,int SIZE> class Stack
{
public:
  void Push(T item);
  T& Pop();
private:
  T internal_array[SIZE];
};
template <class T,int SIZE> void Stack<T,SIZE>::Push(T item) {};
template <class T,int SIZE> T& Stack<T,SIZE>::Pop() {};

////////////////////////////////// usage /////////////////////////////////////
int twelve = template_min<char,int>(12,35);
Stack<float,1024> my_stack;
my_stack.Push(3.14);

Standard IO

using namespace std;
#include <iostream>
#include <iomanip>
#include <fstream>

//////////////////////////////////////////////////////////////////////////////
//  name: show_stdio
//  purpose: show usage of standard input / output
//  args: (in)  filename - name of file to work with
//  returns: 0 on success, -1 on failure
//////////////////////////////////////////////////////////////////////////////
int show_stdio(char *filename)
{
  // vars
  fstream input;
  unsigned long dword = 0;

  // open the file in binary mode for read only
  input.open(filename, ios::in | ios::binary);
  if (input.fail())
  {
    cout << "cant open " << filename << endl;
    return -1;
  }
  // read dwords from the file
  while (input.good())  // good is FALSE on eof
  {
    input.read((char*)&dword, sizeof(dword));
    if (!input.fail())
    {
      cout << "read from " << filename << " the ";
      cout << "dword " << hex << setfill('0') << setw(8) << dword << endl;
    }
  }
  // cleanup
  input.close();
  return 0;
}



Powered by Notepad.