- Environment and Compilation
- Core Language Fundamentals
- Memory Management
- Object-Oriented Programming
- Standard Template Library Containers
- Advanced C++ Features
Environment and Compilation
Visual Studio Configuration
When working with Visual Studio, efficient keyboard shortcuts can significantly boost productivity:
- Comment/Uncomment: Ctrl + K + C / Ctrl + K + U
- Select current word: Ctrl + W
- Navigate words: Ctrl + ←/→
- Code completion: Ctrl + J
- Line movement: Alt + ↑/↓
- Insert lines: Ctrl + Enter (above) / Ctrl + Shift + Enter (below)
Header Files
Header files should contain only necessary declarations. Avoid including variable or function definitions except for class definitions, const objects, and inline functions. Prevent multiple inclusion of the same header using include guards.
Include Guards
There are two primary approaches to header protection:
Using #ifndef (Traditional Approach)
#ifndef MYCLASS_H
#define MYCLASS_H
// Class declarations and inline functions
#endif // MYCLASS_H
Advantages: Cross-platform compatibility
Disadvantages: Risk of macro name conflicts, slower compilation in large projects
Using #pragma once (Modern Approach)
#pragma once
// Class declarations and inline functions
Advantages: No macro naming conflicts, faster compilation in large projects
Disadvantages: Limited compiler support, less portable
Precompiled Headers
Precompiled headers (like stdafx.h) improve compilation speed by compiling header files into binary format. They're particularly useful when most source files require the same headers or when frequently using code across multiple files.
Core Language Fundamentals
Basic Types
Understanding type sizes is fundamental:
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned int size_t;
Best practice: Use specific-length types (e.g., int32_t) instead of built-in types like int for better portability.
Constant Qualifier
The const keyword defines values that cannot be modified after initialization. Constants must be initialized at declaration.
Top-level vs. Bottom-level Const
Top-level const indicates the pointer itself is constant:
int *const cp = &j;
Bottom-level const indicates the pointed-to object is constant:
const int *cptr = &i;
References
References are aliases to objects that must be initialized with a compatible object. Once defined, a reference cannot be bound to another object.
References to const objects can be initialized with non-const objects, but the reference itself cannot modify the object.
Type Specifiers
auto Type Specifier
auto allows type deduction based on initializers. It typically ignores top-level const but retains bottom-level const.
auto varName = value; // Type deduced from value
decltype Type Specifier
decltype determines the type of an expression without evaluating it, allowing declaration of variables with specific types.
decltype(expression) varName; // Type determined by expression
Dynamic Memory Allocation
new and delete Operators
The new operator allocates memory on the heap and returns a pointer to the allocated object. delete frees this memory.
ClassName *obj = new ClassName();
// Use the object
delete obj;
obj = nullptr; // Prevent dangling pointer
Pointers
Pointers store addresses of other objects. They must be initialized to avoid undefined behavior.
int value = 42;
int *ptr = &value; // Pointer to value
cout << *ptr << endl; // Dereference operator
void Pointers
void* pointers can store addresses of any type but cannot perform operations on the objects they point to. They're useful for generic interfaces.
Const Pointers
Pointers to const objects cannot modify what they point to but can be reassigned to point elsewhere.
Functions
Parameter Passing
Parameters can be passed by value (default), by reference, or by pointer. Reference parameters directly modify the original argument.
Default Arguments
Functions can have default arguments that are used when callers don't provide values. Place parameters with fewer defaults first in the paramter list.
Memory Management
Smart Pointers
Smart pointers automatically manage memory, preventing leaks and dangling pointers. Modern C++ provides three types:
shared_ptr
shared_ptr allows multiple pointers to share ownership of an object. The object is destroyed when the last shared_ptr is destroyed.
#include <memory>
auto sp = std::make_shared<int>(42); // Preferred way to create shared_ptr
cout << sp.use_count() << endl; // Number of shared owners</int></memory>
unique_ptr
unique_ptr owns an object exclusively and cannot be copied, only moved.
std::unique_ptr<int> up1(new int(10));
std::unique_ptr<int> up2 = std::move(up1); // Ownership transferred</int></int>
weak_ptr
weak_ptr provides non-owning access to an object managed by shared_ptr, breaking reference cycles.
std::shared_ptr<int> sp = std::make_shared<int>(42);
std::weak_ptr<int> wp(sp); // Doesn't affect reference count</int></int></int>
Object-Oriented Programming
Classes
Classes define types that bundle data and operations. If not explicitly defined, the compiler provides default constructors, destructor, and copy/move operations.
Member Functions
Member functions can access private members of their class. They can be defined inline for performance optimization.
const Member Functions
Functions declared with const cannot modify the object they operate on.
Constructors
Constructors initialize objects. If no constructor is defined, the compiler provides a default one. Use =default to explicitly request compiler-generated implementations.
Destructors
Destructors release resources when objects are destroyed. Virtual destructors ensure proper cleanup in inheritance hierarchies.
Copy Control
Classes can define copy/move constructors and assignment operators to control object copying. Default implementations perform shallow copying.
Friend Declarations
friend grants non-member functions or other classes access to private members.
Static Members
Static members are shared among all instances of a class and don't belong to specific objects.
Inheritance
Derivation allows creating specialized classes based on existing ones. Base class members can be accessed through derived class objects.
Multiple Inheritance
Classes can inherit from multiple base classes. Constructor order follows base class declaration order, not initialization list order.
Virtual Functions
Virtual functions enable runtime polymorphism. Use override to explicitly indicate a function is overriding a base class virtual function.
Pure Virtual Functions
Functions declared with = 0 are pure virtual, making their classes abstract. Abstract classes define interfaces but cannot be instantiated.
Access Control
public, protected, and private keywords control member access. protected members are accessible to derived classes.
Standard Template Library Containers
Iterators
Iterators provide generalized pointers to container elements. Container operations often return iterators to access elements.
Sequence Containers
Vector
Vector provides dynamic arrays with fast random access. It automatically manages memory growth.
Container Growth
When capacity is exhausted, vector typically reallocates with increased capacity (implementation-specific growth factor).
std::vector<int> vec;
vec.reserve(100); // Preallocate space for at least 100 elements</int>
Container Operations
Sequence containers provide operations for element insertion, deletion, and access.
push_back vs. emplace_back
push_back adds a copy or move of an existing element to the container. emplace_back constructs elements directly in container memory, avoiding temporary objects.
std::vector<myclass> vec;
vec.push_back(MyClass(1, 2)); // Creates temporary object
vec.emplace_back(1, 2); // Constructs directly in memory</myclass>
Container Adapters
Container adapters provide restricted interfaces for specific access patterns:
- stack: LIFO (Last-In-First-Out)
- queue: FIFO (First-In-First-Out)
- priority_queue: Priority-based access
Associative Containers
Associative containers store elements with keys for fast lookup:
- map: Key-value pairs
- set: Unique keys only
- multimap/multiset: Keys can be repeated
- unordered variants: Hash-based implementation
Custom Ordering
Associative containers can use custom comparison functions:
struct CustomCompare {
bool operator()(const Type& a, const Type& b) {
return a.customField < b.customField;
}
};
std::set<type customcompare=""> customSet;</type>
Advanced C++ Features
Rvalue References
Rvalue references (&&) bind to temporary objects and enable move semantics, improving performance when transferring resources.
void processValue(int&& val) {
// Can modify temporary value
val = 42;
}
Universal References
When declared as T&& in template contexts, references can bind to both lvalues and rvalues, enabling perfect forwarding.
template<typename t="">
void wrapper(T&& param) {
// Forward param to another function
process(std::forward<t>(param));
}</t></typename>
Perfect Forwarding
template>void process(T&& param); ### Move Semantics
Move constructors and assignmant operators transfer resources from temporary objects rather than copying them.
class ResourceHolder {
Resource* resource;
public:
ResourceHolder(ResourceHolder&& other) noexcept
: resource(other.resource) {
other.resource = nullptr;
}
};