summaryrefslogtreecommitdiffhomepage
path: root/c++.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'c++.html.markdown')
-rw-r--r--c++.html.markdown590
1 files changed, 590 insertions, 0 deletions
diff --git a/c++.html.markdown b/c++.html.markdown
new file mode 100644
index 00000000..9f357b08
--- /dev/null
+++ b/c++.html.markdown
@@ -0,0 +1,590 @@
+---
+language: c++
+filename: learncpp.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+lang: en
+---
+
+C++ is a systems programming language that,
+[according to its inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+was designed to
+
+- be a "better C"
+- support data abstraction
+- support object-oriented programming
+- support generic programming
+
+Though its syntax can be more difficult or complex than newer languages,
+it is widely used because it compiles to native instructions that can be
+directly run by the processor and offers tight control over hardware (like C)
+while offering high-level features such as generics, exceptions, and classes.
+This combination of speed and functionality makes C++
+one of the most widely-used programming languages.
+
+```c++
+//////////////////
+// Comparison to C
+//////////////////
+
+// C++ is _almost_ a superset of C and shares its basic syntax for
+// variable declarations, primitive types, and functions.
+// However, C++ varies in some of the following ways:
+
+// A main() function in C++ should return an int,
+// though void main() is accepted by most compilers (gcc, clang, etc.)
+// This value serves as the program's exit status.
+// See http://en.wikipedia.org/wiki/Exit_status for more information.
+int main(int argc, char** argv)
+{
+ // Command line arguments are passed in by argc and argv in the same way
+ // they are in C.
+ // argc indicates the number of arguments,
+ // and argv is an array of C-style strings (char*)
+ // representing the arguments.
+ // The first argument is the name by which the program was called.
+ // argc and argv can be omitted if you do not care about arguments,
+ // giving the function signature of int main()
+
+ // An exit status of 0 indicates success.
+ return 0;
+}
+
+// In C++, character literals are one byte.
+sizeof('c') == 1
+
+// In C, character literals are the same size as ints.
+sizeof('c') == sizeof(10)
+
+
+// C++ has strict prototyping
+void func(); // function which accepts no arguments
+
+// In C
+void func(); // function which may accept any number of arguments
+
+// Use nullptr instead of NULL in C++
+int* ip = nullptr;
+
+// C standard headers are available in C++,
+// but are prefixed with "c" and have no .h suffix.
+#include <cstdio>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+///////////////////////
+// Function overloading
+///////////////////////
+
+// C++ supports function overloading
+// provided each function takes different parameters.
+
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // Resolves to void print(const char*)
+ print(15); // Resolves to void print(int)
+}
+
+/////////////////////////////
+// Default function arguments
+/////////////////////////////
+
+// You can provide default arguments for a function
+// if they are not provided by the caller.
+
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // Do something with the ints here
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// Default arguments must be at the end of the arguments list.
+
+void invalidDeclaration(int a = 1, int b) // Error!
+{
+}
+
+
+/////////////
+// Namespaces
+/////////////
+
+// Namespaces provide separate scopes for variable, function,
+// and other declarations.
+// Namespaces can be nested.
+
+namespace First {
+ namespace Nested {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // end namespace Nested
+} // end namespace First
+
+namespace Second {
+ void foo()
+ {
+ printf("This is Second::foo\n")
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // Assume everything is from the namespace "Second"
+ // unless otherwise specified.
+ using namespace Second;
+
+ foo(); // prints "This is Second::foo"
+ First::Nested::foo(); // prints "This is First::Nested::foo"
+ ::foo(); // prints "This is global foo"
+}
+
+///////////////
+// Input/Output
+///////////////
+
+// C++ input and output uses streams
+// cin, cout, and cerr represent stdin, stdout, and stderr.
+// << is the insertion operator and >> is the extraction operator.
+
+#include <iostream> // Include for I/O streams
+
+using namespace std; // Streams are in the std namespace (standard library)
+
+int main()
+{
+ int myInt;
+
+ // Prints to stdout (or terminal/screen)
+ cout << "Enter your favorite number:\n";
+ // Takes in input
+ cin >> myInt;
+
+ // cout can also be formatted
+ cout << "Your favorite number is " << myInt << "\n";
+ // prints "Your favorite number is <myInt>"
+
+ cerr << "Used for error messages";
+}
+
+//////////
+// Strings
+//////////
+
+// Strings in C++ are objects and have many member functions
+#include <string>
+
+using namespace std; // Strings are also in the namespace std (standard library)
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + is used for concatenation.
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++ strings are mutable and have value semantics.
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+/////////////
+// References
+/////////////
+
+// In addition to pointers like the ones in C,
+// C++ has _references_.
+// These are pointer types that cannot be reassigned once set
+// and cannot be null.
+// They also have the same syntax as the variable itself:
+// No * is needed for dereferencing and
+// & (address of) is not used for assignment.
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // This creates a reference to foo.
+fooRef += ". Hi!"; // Modifies foo through the reference
+cout << fooRef; // Prints "I am foo. Hi!"
+
+fooRef = bar; // Error: references cannot be reassigned.
+
+const string& barRef = bar; // Create a const reference to bar.
+// Like C, const values (and pointers and references) cannot be modified.
+barRef += ". Hi!"; // Error, const references cannot be modified.
+
+//////////////////////////////////////////
+// Classes and object-oriented programming
+//////////////////////////////////////////
+
+// First example of classes
+#include <iostream>
+
+// Declare a class.
+// Classes are usually declared in header (.h or .hpp) files.
+class Dog {
+ // Member variables and functions are private by default.
+ std::string name;
+ int weight;
+
+// All members following this are public
+// until "private:" or "protected:" is found.
+public:
+
+ // Default constructor
+ Dog();
+
+ // Member function declarations (implementations to follow)
+ // Note that we use std::string here instead of placing
+ // using namespace std;
+ // above.
+ // Never put a "using namespace" statement in a header.
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // Functions that do not modify the state of the object
+ // should be marked as const.
+ // This allows you to call them if given a const reference to the object.
+ // Also note the functions must be explicitly declared as _virtual_
+ // in order to be overridden in derived classes.
+ // Functions are not virtual by default for performance reasons.
+ virtual void print() const;
+
+ // Functions can also be defined inside the class body.
+ // Functions defined as such are automatically inlined.
+ void bark() const { std::cout << name << " barks!\n" }
+
+ // Along with constructors, C++ provides destructors.
+ // These are called when an object is deleted or falls out of scope.
+ // This enables powerful paradigms such as RAII
+ // (see below)
+ // Destructors must be virtual to allow classes to be derived from this one.
+ virtual ~Dog();
+
+}; // A semicolon must follow the class definition.
+
+// Class member functions are usually implemented in .cpp files.
+void Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// Objects (such as strings) should be passed by reference
+// if you are modifying them or const reference if you are not.
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// Notice that "virtual" is only needed in the declaration, not the definition.
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+void Dog::~Dog()
+{
+ cout << "Goodbye " << name << "\n";
+}
+
+int main() {
+ Dog myDog; // prints "A dog has been constructed"
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg"
+ return 0;
+} // prints "Goodbye Barkley"
+
+// Inheritance:
+
+// This class inherits everything public and protected from the Dog class
+class OwnedDog : public Dog {
+
+ void setOwner(const std::string& dogsOwner)
+
+ // Override the behavior of the print function for all OwnedDogs. See
+ // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
+ // for a more general introduction if you are unfamiliar with
+ // subtype polymorphism.
+ // The override keyword is optional but makes sure you are actually
+ // overriding the method in a base class.
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// Meanwhile, in the corresponding .cpp file:
+
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // Call the print function in the base Dog class
+ std::cout << "Dog is owned by " << owner << "\n";
+ // Prints "Dog is <name> and weights <weight>"
+ // "Dog is owned by <owner>"
+}
+
+//////////////////////////////////////////
+// Initialization and Operator Overloading
+//////////////////////////////////////////
+
+// In C++ you can overload the behavior of operators such as +, -, *, /, etc.
+// This is done by defining a function which is called
+// whenever the operator is used.
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // Member variables can be given default values in this manner.
+ double x = 0;
+ double y = 0;
+
+ // Define a default constructor which does nothing
+ // but initialize the Point to the default value (0, 0)
+ Point() { };
+
+ // The following syntax is known as an initialization list
+ // and is the proper way to initialize class member values
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* Do nothing except initialize the values */ }
+
+ // Overload the + operator.
+ Point operator+(const Point& rhs) const;
+
+ // Overload the += operator
+ Point& operator+=(const Point& rhs);
+
+ // It would also make sense to add the - and -= operators,
+ // but we will skip those for brevity.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // Create a new point that is the sum of this one and rhs.
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Point up (0,1);
+ Point right (1,0);
+ // This calls the Point + operator
+ // Point up calls the + (function) with right as its paramater
+ Point result = up + right;
+ // Prints "Result is upright (1,1)"
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+/////////////////////
+// Exception Handling
+/////////////////////
+
+// The standard library provides a few exception types
+// (see http://en.cppreference.com/w/cpp/error/exception)
+// but any type can be thrown an as exception
+#include <exception>
+
+// All exceptions thrown inside the _try_ block can be caught by subsequent
+// _catch_ handlers.
+try {
+ // Do not allocate exceptions on the heap using _new_.
+ throw std::exception("A problem occurred");
+}
+// Catch exceptions by const reference if they are objects
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+// Catches any exception not caught by previous _catch_ blocks
+} catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // Re-throws the exception
+}
+
+///////
+// RAII
+///////
+
+// RAII stands for Resource Allocation Is Initialization.
+// It is often considered the most powerful paradigm in C++,
+// and is the simple concept that a constructor for an object
+// acquires that object's resources and the destructor releases them.
+
+// To understand how this is useful,
+// consider a function that uses a C file handle:
+void doSomethingWithAFile(const char* filename)
+{
+ // To begin with, assume nothing can fail.
+
+ FILE* fh = fopen(filename, "r"); // Open the file in read mode.
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // Close the file handle.
+}
+
+// Unfortunately, things are quickly complicated by error handling.
+// Suppose fopen can fail, and that doSomethingWithTheFile and
+// doSomethingElseWithIt return error codes if they fail.
+// (Exceptions are the preferred way of handling failure,
+// but some programmers, especially those with a C background,
+// disagree on the utility of exceptions).
+// We now have to check each call for failure and close the file handle
+// if a problem occurred.
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Open the file in read mode
+ if (fh == nullptr) // The returned pointer is null on failure.
+ reuturn false; // Report that failure to the caller.
+
+ // Assume each function returns false if it failed
+ if (!doSomethingWithTheFile(fh)) {
+ fclose(fh); // Close the file handle so it doesn't leak.
+ return false; // Propagate the error.
+ }
+ if (!doSomethingElseWithIt(fh)) {
+ fclose(fh); // Close the file handle so it doesn't leak.
+ return false; // Propagate the error.
+ }
+
+ fclose(fh); // Close the file handle so it doesn't leak.
+ return true; // Indicate success
+}
+
+// C programmers often clean this up a little bit using goto:
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ reuturn false;
+
+ if (!doSomethingWithTheFile(fh))
+ goto failure;
+
+ if (!doSomethingElseWithIt(fh))
+ goto failure;
+
+ fclose(fh); // Close the file
+ return true; // Indicate success
+
+failure:
+ fclose(fh);
+ return false; // Propagate the error
+}
+
+// If the functions indicate errors using exceptions,
+// things are a little cleaner, but still sub-optimal.
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Open the file in read mode
+ if (fh == nullptr)
+ throw std::exception("Could not open the file.");
+
+ try {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...) {
+ fclose(fh); // Be sure to close the file if an error occurs.
+ throw; // Then re-throw the exception.
+ }
+
+ fclose(fh); // Close the file
+ // Everything succeeded
+}
+
+// Compare this to the use of C++'s file stream class (fstream)
+// fstream uses its destructor to close the file.
+// Recall from above that destructors are automatically called
+// whenver an object falls out of scope.
+void doSomethingWithAFile(const std::string& filename)
+{
+ // ifstream is short for input file stream
+ std::ifstream fh(filename); // Open the file
+
+ // Do things with the file
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // The file is automatically closed here by the destructor
+
+// This has _massive_ advantages:
+// 1. No matter what happens,
+// the resource (in this case the file handle) will be cleaned up.
+// Once you write the destructor correctly,
+// It is _impossible_ to forget to close the handle and leak the resource.
+// 2. Note that the code is much cleaner.
+// The destructor handles closing the file behind the scenes
+// without you having to worry about it.
+// 3. The code is exception safe.
+// An exception can be thrown anywhere in the function and cleanup
+// will still occur.
+
+// All idiomatic C++ code uses RAII extensively for all resources.
+// Additional examples include
+// - Memory using unique_ptr and shared_ptr
+// - Containers - the standard library linked list,
+// vector (i.e. self-resizing array), hash maps, and so on
+// all automatically destroy their contents when they fall out of scope.
+// - Mutexes using lock_guard and unique_lock
+```
+Futher Reading:
+
+An up-to-date language reference can be found at
+<http://cppreference.com/w/cpp>
+
+Additional resources may be found at <http://cplusplus.com>