C++

From Colettapedia
Jump to navigation Jump to search

General

  • Copy one file into another:
#include <fstream>
#include <string>

int main(){
     
     //Open file for reading
     std::ifstream in("input.dat");
     
     //Open file for writing
     std::ofstream out("output.dat");
     
     //Temporary buffer for line read from file
     std::string line;
     
     while(getline(in,line)){//getline removes the newline char
          out<<line<<'\n';   // Appending back newline char  
     }
     return 0;
}

stdlib

  • strchr() vs strrchr() - returns pointer to first and last instance of a specified character, respectively.

ostream

  • cout, cerr, clog are special instances of the class ostream
  • header <fstream>
    • class ofstream is a type of ostream, and is used for writing data to files. (replaces fprintf)
    • class ifstream is a type of istream, and is for reading data from files (replaces fopen)
    • pass a string literal, or a string.c_str() to declare either of these
  • the function ios::rdbuf() is both a get and set function that allows for the redirecting of output.

cstdlib

  • char* getenv( const char* name )

Preprocessor

  • #pragma directives - offer a way for each compiler to offer machine- and operating system-specific features while retaining overall compatibility with the C and C++ languages.
    • Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler.
    • Pragmas can be used in conditional statements, to provide new preprocessor functionality, or to provide implementation-defined information to the compiler.

Polymorphism and Inheritance

  • You must explicitly specify the accessibility of the inherited class when declaring the inheriting class
    • class inheriting : public inherited { ... };
      • NOTE THE PLACEMENT OF PUBLIC ABOVE
  • Make sure the parent constructor is called by using the initialization list notation
class Foo : public parent_class
{
        Foo() : parent_class( "arg" ) // sample initialization list
        {
                // you must include a body, even if it's merely empty
        }
};
  • If you don't explicitly define the three mandatory things every class should do, the compiler will try to provide them for you
    1. default constructor (e.g., TFoo::TFoo()) - initialize itself to a default state
    2. copy constructor (TFoo::TFoo(const TFoo&)) - initialize itself from another instance of the same class
    3. assignment operator (TFoo::operator=(const TFoo&)) - assume the semantic state of another instance of the same class

default constructor

    • If you don't want a class to be copied, for example, you have to define an empty copy constructor and assignment operator yourself and make them private or protected.

Function Pointers

  • Define a function pointer and initialize to NULL
  1. int (*pt2Function)(float, char, char) = NULL;
    • C-style
  2. int (TMyClass::*pt2Member)(float, char, char) = NULL;
    • C++-style
  3. int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
    • C++-style, constant
  • Remember that the functions that are being passed via pointers are going to be executed outside of the class scope, so they should be made public
  • Use the keyword "static" within the interface declaration (.h file), but leave out the static keyword before the function's implementation in the .cpp file

Exception Handling

  • syntax
try {
  // code here
}
catch (int param) { cout << "int exception"; }
catch (char param) { cout << "char exception"; }
catch (...) { cout << "default exception"; }
  • You can #include <sdtexcept> for standard exceptions
    • Catch the base class "exception" -> catch (exception& e)
  • can nest try-catch blocks
  • It is recommended to include all dynamic memory allocations within a try block that catches this type of exception to perform a clean action instead of an abnormal program termination
  • Cancel the ability of a functions to throw exceptions by specifying "throw()" in the function declaration
    • int myfunction (int param) throw(); // no exceptions allowed
    • float myfunction (char param) throw (int); // only int exceptions allowed to be thrown
  • After an exception has been handled the program execution resumes after the try-catch block, not after the throw statement!.

Pointers

  • References and pointers are two different things
    • Can't just go "if (this == that)"
    • if (*this == that) - Tests semantic equality. Calls classes equality operator, which isn't already created for you. And even if it is, it would theoretically go through and test every member for equality. Very slow.
    • if (this == &that) - Tests identity. A simple pointer comparison. "if (this == &that)" will return true only if this and that refer to the same object, not merely to two objects that "look the same."
  • Owning pointers vs. aliasing pointers
    • one and only one delete for each owning pointer.
  • foo_class* my_foo = new foo_class(*their_foo);
    • But, if my_foo is a member of a class, you have to delete what's there before you assign it something new and leave the previously allocated memory hanging...
    • delete my_foo; my_foo = new foo_class(*their_foo);
  • auto_ptr<AnyClass> - ANSI C++ standard -

Creating an Assignment Operator

  • The Anatomy of the Assignment Operator - read and learn the shit out of this article.
  • Standard C operators need to return a reference the left hand side of the operator to enable daisy-chaining of operations: x = y = z = 3; Usually just end it with "return *this;"
  • Take only one param, pass by reference, make it const, usually an instance of the same class as the thing you're assigning, have to overload for other things.
  • one correct answer:
TFoo&
TFoo::operator=(const TFoo& that)
{
    if (this != &that) {
        TBar* bar1 = 0;
        TBar* bar2 = 0;

        // Use try/catch block to atomicize/transactionalise
        try {
            bar1 = new TBar(*that.fBar1);
            bar2 = new TBar(*that.fBar2);
        }
        catch (...) {
            delete bar1;
            delete bar2;
            throw;
        }

        // Since TFoo inherits from TSuperFoo,
        // have to call assignment operator for base class
        TSuperFoo::operator=(that);

        // MUST delete fBar points to before you clobber the
        // pointer to point at something else
        delete fBar1;
        fBar1 = bar1;
        delete fBar2;
        fBar2 = bar2;
    }
    return *this;
}
  • better answer = use the member's assignment operator:
TFoo&
TFoo::operator=(const TFoo& that)
{
    TSuperFoo::operator=(that);
    *fBar1 = *(that.fBar1);
    *fBar2 = *(that.fBar2);

    return *this;
}

Classes

  • Can define classes within classes
    • Access using multiple scope operators: OuterClass::InnerClass::Function(args)

std::map

  • by definition, elements in a map are automatically ordered. For true unordered hash table, use unordered_map
  • built off of std::pair which is defined in <utility>
  • std::map<Key, Data [, Compare, Alloc>
  • can insert a key/val pair by simply using [] operator, or .insert() method
  • access elements using iterator and it->first for key, and it->second for value
std::map<std::string, int> wordcounts;
std::string s;
std::cin >> s;
wordcounts[s]++;
wordcounts.insert(std::pair<std::string, int>("twenty seven", 27));

typedef std::map<std::string, int> StringIntMap;
wordcounts.insert(StringIntMap::value_type("four", 4)); //apparently all stl containers have this method
  • map::begin() - returns iterator referring to first element in map container
  • map::clear() - clears out map
  • map::count( KeyType the_key) - returns 1 if the_key is in the map, 0 otherwise
  • bool map::empty() - is empty?
  • map::end() - return iterator referring to last element
  • map::erase() - used to delete key value pairs from map
  • map::find(the_key) - returns iterator to the_key

std::vector

  • use reserve member function to preallocate memory

std::set

  • automatically ordered group of unique things
  • like an ordered hash table where there are no values, just keys

Eigen