diff --git a/docs/programming-fundamentals/oop-basics/attributes.md b/docs/programming-fundamentals/oop-basics/attributes.md new file mode 100644 index 000000000..0e2b555c7 --- /dev/null +++ b/docs/programming-fundamentals/oop-basics/attributes.md @@ -0,0 +1,212 @@ +--- +id: attributes +title: "Attributes" +sidebar_label: "Attributes" +sidebar_position: 7 +description: "Deep dive into attributes (data members) in C++ classes: object state, fields vs properties, getters/setters, and encapsulation techniques." +tags: [Attributes, Data-Members, Encapsulation, Getters-Setters, OOP] +--- +# Attributes in C++ + +Attributes, also known as data members or fields, represent the state of an object in a C++ class. They store the data that defines an object's characteristics and enable data encapsulation. + +## 1. Introduction to Attributes + +**Definition:** +Attributes are variables declared inside a class that hold the data (state) of objects created from that class. + +**Key Concepts:** +- **Object State:** The current values of all attributes of an object. +- **Data Representation:** How real-world entities are modeled using primitive or complex data types within a class. + +**Syntax:** +```cpp +class ClassName { +public: + // Attribute declarations + data_type attributeName; +}; +``` + +**Example - Basic Attributes:** +```cpp +#include +#include +using namespace std; + +class Student { +public: + string name; // Attribute + int rollNo; // Attribute + float gpa; // Attribute +}; + +int main() { + Student s1; + s1.name = "Alice"; + s1.rollNo = 101; + s1.gpa = 9.2; + + cout << "Name: " << s1.name << endl; + cout << "Roll No: " << s1.rollNo << endl; + cout << "GPA: " << s1.gpa << endl; + return 0; +} +``` + +**Output:** +```text +Name: Alice +Roll No: 101 +GPA: 9.2 +``` + +## 2. Fields vs Properties + +In C++, we primarily work with **fields** (data members). The term "Properties" is more common in languages like C# with built-in support for getters/setters. In C++, we simulate properties using **getters and setters**. + +| Aspect | Fields (Data Members) | Properties (Simulated in C++) | +|---------------------|----------------------------------------|--------------------------------------------| +| Direct Access | Can be public (direct access) | Controlled via getter/setter methods | +| Validation | No built-in validation | Validation possible in setters | +| Encapsulation | Low if public | High (data hiding) | +| Syntax | Simple variable declaration | Pair of member functions | +| Memory | Direct storage | No extra storage (just methods) | + +**Recommendation:** Prefer private fields + public getters/setters for better design. + +## 3. Getters and Setters + +Getters (accessors) retrieve attribute values. +Setters (mutators) modify attribute values with optional validation. + +**Example:** +```cpp +#include +using namespace std; + +class BankAccount { +private: + double balance = 0.0; // Private field + +public: + // Getter + double getBalance() const { + return balance; + } + + // Setter with validation + void setBalance(double newBalance) { + if (newBalance >= 0) { + balance = newBalance; + } else { + cout << "Error: Balance cannot be negative!" << endl; + } + } + + void deposit(double amount) { + if (amount > 0) { + balance += amount; + } + } +}; + +int main() { + BankAccount acc; + acc.setBalance(5000.0); + cout << "Balance: " << acc.getBalance() << endl; + acc.deposit(1500.0); + cout << "Balance after deposit: " << acc.getBalance() << endl; + return 0; +} +``` + +**Output:** +```text +Balance: 5000 +Balance after deposit: 6500 +``` + +**Benefits of Getters/Setters:** +- Control read/write access +- Add validation logic +- Enable future changes without breaking client code (interface remains the same) + +## 4. Data Encapsulation Techniques + +Encapsulation is the bundling of data (attributes) and methods that operate on that data within a class, while restricting direct access to some components. + +### Access Specifiers for Encapsulation + +| Specifier | Class | Derived Class | Outside Class | Use Case | +|-------------|-------|---------------|---------------|---------------------------| +| `public` | Yes | Yes | Yes | Interface methods | +| `protected` | Yes | Yes | No | Inheritance hierarchy | +| `private` | Yes | No | No | Internal state (most attributes) | + +**Best Practice:** Make data members `private` and expose them only through public methods. + +**Advanced Encapsulation Techniques:** +1. **Immutable Objects** — Use `const` and remove setters. +2. **PImpl Idiom** — Hide implementation details. +3. **Const Correctness** — Use `const` member functions for getters. + +**Example - Strong Encapsulation:** +```cpp +#include +using namespace std; + +class Rectangle { +private: + double length; + double width; + +public: + Rectangle(double l, double w) : length(l), width(w) {} + + double getArea() const { + return length * width; + } + + // Controlled modification (no direct setters) + void scale(double factor) { + if (factor > 0) { + length *= factor; + width *= factor; + } + } +}; + +int main() { + Rectangle rect(5.0, 3.0); + cout << "Area: " << rect.getArea() << endl; + rect.scale(2.0); + cout << "Area after scaling: " << rect.getArea() << endl; + return 0; +} +``` + +**Output:** +```text +Area: 15 +Area after scaling: 60 +``` + +## 5. Best Practices for Attributes + +- **Prefer Initialization** in constructors over assignment in the body. +- **Use `const`** for attributes that should not change after construction. +- **Avoid public data members** unless in simple data structs (`struct`). +- **Group related attributes** logically. +- **Minimize class size** — only store necessary state. +- **Use meaningful names** (e.g., `customerEmail` instead of `e`). +- **Prefer `std::string`** over C-style strings for text attributes. +- **Consider thread safety** for shared mutable state. + +**Why Encapsulation Matters:** +- Protects object integrity +- Reduces coupling between classes +- Makes code easier to maintain and debug +- Supports future evolution of internal representation + +--- diff --git a/docs/programming-fundamentals/oop-basics/constructors.md b/docs/programming-fundamentals/oop-basics/constructors.md new file mode 100644 index 000000000..c6fe17061 --- /dev/null +++ b/docs/programming-fundamentals/oop-basics/constructors.md @@ -0,0 +1,636 @@ +--- + +id: constructors + +title: "Constructors" + +sidebar_label: "Constructors" + +sidebar_position: 7 + +description: "Comprehensive guide to constructors in C++ - purpose, types, overloading, chaining, initialization lists, and best practices." + +tags: [Constructors, Default_Constructor, Parameterized_Constructor, Copy_Constructor, Initialization_List, Constructor_Overloading] + +--- + + +# Constructors in C++ + + +Constructors are special member functions in C++ that are automatically invoked when an object of a class is created. They are primarily used to *initialize** the data members of the class. + +--- + +## 1. Introduction to Constructors + + + +**Purpose:** + + - Initialize objects with valid state. + + - Allocate resources (memory, files, etc.). + + - Enforce invariants. + + - Provide default values. + + + + * *Key Characteristics: * * + + - Same name as the class. + + - No return type (not even `void`). + + - Can be overloaded. + + - Automatically called upon object creation. + + - Can be defined inside or outside the class. + + + + * *Types of Constructors: * * + + - Default Constructor + + - Parameterized Constructor + + - Copy Constructor + + - Move Constructor (C++11) + + - Conversion Constructor + + + + --- + + + + ## 2. Default Constructor + + + +A constructor with no parameters. If no constructor is defined, the compiler provides a default one (which does nothing for POD types). + + + + * *Example: * * + +```cpp + + #include + +using namespace std; + + + +class Student { + +public: + + string name; + + int rollNo; + + + + // Default Constructor + + Student() { + + name = "Unknown"; + + rollNo = 0; + + cout << "Default Constructor called" << endl; + + } + +}; + + + +int main() { + + Student s1; // Default constructor called + + cout << s1.name << " - " << s1.rollNo << endl; + + return 0; + +} + +``` + + + + * *Output: * * + +```text + +Default Constructor called + +Unknown - 0 + +``` + + + + --- + + + + ## 3. Parameterized Constructor + + + +Constructors with parameters for custom initialization. + + + +```cpp + + #include + +using namespace std; + + + +class Student { + +public: + + string name; + + int rollNo; + + + + // Parameterized Constructor + + Student(string n, int r) { + + name = n; + + rollNo = r; + + cout << "Parameterized Constructor called" << endl; + + } + +}; + + + +int main() { + + Student s1("Alice", 101); + + cout << s1.name << " - " << s1.rollNo << endl; + + return 0; + +} + +``` + + + + * *Output: * * + +```text + +Parameterized Constructor called + +Alice - 101 + +``` + + + + --- + + + + ## 4. Constructor Overloading + + + +Multiple constructors with different parameter lists. + + + + * *Example: * * + +```cpp + + #include + +using namespace std; + + + +class Rectangle { + +public: + + int length, width; + + + + // Default + + Rectangle() : length(0), width(0) {} + + + + // Single parameter (Square) + + Rectangle(int side) : length(side), width(side) {} + + + + // Two parameters + + Rectangle(int l, int w) : length(l), width(w) {} + + + + void area() { + + cout << "Area: " << length * width << endl; + + } + +}; + + + +int main() { + + Rectangle r1; // Default + + Rectangle r2(5); // Square + + Rectangle r3(4, 6); // Rectangle + + + + r1.area(); + + r2.area(); + + r3.area(); + + return 0; + +} + +``` + + + + * *Output: * * + +```text + +Area: 0 + +Area: 25 + +Area: 24 + +``` + + + + --- + + + + ## 5. Constructor Chaining / Delegation + + + +One constructor can call another constructor of the same class (C++11+). + + + + * *Example: * * + +```cpp + + #include + +using namespace std; + + + +class Person { + +public: + + string name; + + int age; + + + + // Delegating constructor + + Person() : Person("Anonymous", 0) { + + cout << "Default constructor (delegated)" << endl; + + } + + + + Person(string n) : Person(n, 0) { + + cout << "Name-only constructor" << endl; + + } + + + + Person(string n, int a) : name(n), age(a) { + + cout << "Full parameterized constructor" << endl; + + } + +}; + + + +int main() { + + Person p1; + + Person p2("Bob"); + + Person p3("Charlie", 25); + + return 0; + +} + +``` + + + + --- + + + + ## 6. Copy Constructor + + + +Used to create a new object as a copy of an existing object. + + + + * *Example: * * + +```cpp + + #include + +using namespace std; + + + +class Student { + +public: + + string name; + + int rollNo; + + + + // Copy Constructor + + Student(const Student & other) { + + name = other.name; + + rollNo = other.rollNo; + + cout << "Copy Constructor called" << endl; + + } + + + + Student(string n, int r) : name(n), rollNo(r) {} + +}; + + + +int main() { + + Student s1("David", 102); + + Student s2 = s1; // Copy Constructor called + + Student s3(s1); // Copy Constructor called + + + + cout << s2.name << endl; + + return 0; + +} + +``` + + + + * *Note: * * If not defined, compiler generates a shallow copy (member-wise). + + + + --- + + + + ## 7. Member Initializer List + + + +Preferred way to initialize members (especially `const`, references, and base classes). + + + + * *Example: * * + +```cpp + +class Test { + + const int value; + +public: + + Test(int v) : value(v) { // Must use initializer list for const + + // value = v; // ERROR + + } + +}; + +``` + + + + * *Benefits: * * + + - Better performance (avoids double initialization). + + - Required for certain members. + + + + --- + + + + ## 8. Practical Example: Complex Number Class + + + +```cpp + + #include + +using namespace std; + + + +class Complex { + +public: + + double real, imag; + + + + // Default + + Complex() : real(0.0), imag(0.0) {} + + + + // Parameterized + + Complex(double r, double i) : real(r), imag(i) {} + + + + // Copy Constructor + + Complex(const Complex & c) : real(c.real), imag(c.imag) {} + + + + void display() const { + + cout << real << " + " << imag << "i" << endl; + + } + +}; + + + +int main() { + + Complex c1; // Default + + Complex c2(3.5, 2.5); // Parameterized + + Complex c3 = c2; // Copy + + + + c1.display(); + + c2.display(); + + c3.display(); + + return 0; + +} + +``` + + + + --- + + + + ## 9. Best Practices & Important Points + + + + - Always provide a default constructor if you define any other constructor (Rule of Three/Five). + + - Use initializer lists whenever possible. + + - Make copy constructor explicit if needed to prevent unwanted copies. + + - Consider `= default` and `= delete` (C++11). + + - Virtual destructors when using inheritance with polymorphism. + + - Avoid heavy computation in constructors. + + + + * *Common Pitfalls: * * + + - Forgetting to initialize pointers → dangling pointers. + + - Order of initialization in initializer list must match declaration order. + + - Using `this` in constructor initializer list carefully. + + + + --- + + + + ## 10. Related Topics + + + + - Destructors + + - Rule of Three/Five/Zero + + - Move Semantics (Move Constructor & Move Assignment) + + + +This covers the fundamentals of constructors, which form the backbone of proper object initialization in C++. + +``` + + + +This matches the style of previous docs. + diff --git a/docs/programming-fundamentals/oop-basics/inheritance.md b/docs/programming-fundamentals/oop-basics/inheritance.md index 6a94527de..67b4cd914 100644 --- a/docs/programming-fundamentals/oop-basics/inheritance.md +++ b/docs/programming-fundamentals/oop-basics/inheritance.md @@ -11,11 +11,9 @@ tags: [Inheritance, Types_of_inheritance, Diamond_problem, basics] Inheritance is a fundamental feature of Object-Oriented Programming (OOP) that allows a new class (derived class) to acquire properties and behavior (data members and member functions) of an existing class (base class). It promotes code reuse, logical hierarchy, and polymorphism. ---- - ## 1. Introduction to Inheritance -**Definition:** +**Definition:** Inheritance is a mechanism where one class can inherit the properties (data members) and functionalities (member functions) of another class. **Key Terminology:** @@ -36,7 +34,6 @@ class DerivedClass : access-specifier BaseClass { :::note Multiple Base Classes: If multiple base classes are present, then they are separated using commas. Order in which the base classes are written matters! - *Example:* ```cpp class DerivedClass : access-specifier1 BaseClass1, access-specifier2 BaseClass2, access-specifier3 BaseClass3 ... @@ -44,25 +41,25 @@ class DerivedClass : access-specifier1 BaseClass1, access-specifier2 BaseClass2, ::: **Access Specifiers in Inheritance:** + The access-specifier determines how the members of the base class are treated in the derived class. -| Base Class Member Access | Public Inheritance | Protected Inheritance | Private Inheritance | -|--------------------------|------------------------|------------------------|----------------------| -| `public` | `public` in derived | `protected` in derived | `private` in derived | -| `protected` | `protected` in derived | `protected` in derived | `private` in derived | -| `private` | Not accessible | Not accessible | Not accessible | +| Base Class Member Access | Public Inheritance | Protected Inheritance | Private Inheritance | +|--------------------------|--------------------|-----------------------|---------------------| +| `public` | `public` in derived| `protected` in derived| `private` in derived| +| `protected` | `protected` in derived| `protected` in derived| `private` in derived| +| `private` | Not accessible | Not accessible | Not accessible | **Why use inheritance?** - Reusability: Avoid rewriting common code. - Extensibility: Add new features to existing classes without modifying them. - Polymorphism: Use base class pointers/references to operate on derived objects. - ## 2. Single Inheritance + A derived class inherits from exactly one base class. **Example:** - ```cpp #include using namespace std; @@ -85,25 +82,23 @@ public: int main() { Car myCar; - myCar.start(); // Inherited from Vehicle - myCar.honk(); // Own method + myCar.start(); // Inherited from Vehicle + myCar.honk(); // Own method return 0; } ``` **Output:** - ```text Vehicle started. Car honks. ``` - ## 3. Multiple Inheritance + A derived class inherits from more than one base class simultaneously. **Example:** - ```cpp #include using namespace std; @@ -139,7 +134,6 @@ int main() { ``` **Output:** - ```text Engine started. Wheels rotating. @@ -148,15 +142,13 @@ Car is driving. **Ambiguity** - Ambiguity can happen when two base classes have member functions with the same name. -- In such a case, if that function is called, it can be confusing as to which of the two functions is called. -- Can be resolved using scope resolution (`Base::function()`). - +- Resolved using scope resolution operator (`Base::function()`). ## 4. Multilevel Inheritance + In multilevel inheritance, a derived class becomes the base class for another class, forming a chain. **Example:** - ```cpp #include using namespace std; @@ -184,27 +176,25 @@ public: int main() { Dog myDog; - myDog.breathe(); // From Animal - myDog.giveBirth(); // From Mammal - myDog.bark(); // Own method + myDog.breathe(); // From Animal + myDog.giveBirth(); // From Mammal + myDog.bark(); // Own method return 0; } ``` **Output:** - ```text Animal breathes. Mammal gives birth. Dog barks. ``` - ## 5. Hierarchical Inheritance + Multiple derived classes inherit from a single base class. This represents a parent-child tree structure. **Example:** - ```cpp #include using namespace std; @@ -234,7 +224,6 @@ int main() { Circle c; c.shapefunc(); c.radius(); - Square s; s.shapefunc(); s.side(); @@ -243,7 +232,6 @@ int main() { ``` **Output:** - ```text This is a shape. Circle has radius. @@ -251,12 +239,11 @@ This is a shape. Square has sides. ``` - ## 6. Hybrid Inheritance -Hybrid inheritance is a combination of two or more types of inheritance (e.g., hierarchical + multiple, multilevel + multiple). Not every hybrid inheritance creates ambiguity – it only becomes problematic when it forms a diamond. -**Example (Hybrid = Hierarchical + Multiple):** +Hybrid inheritance is a combination of two or more types of inheritance (e.g., hierarchical + multiple, multilevel + multiple). +**Example (Hybrid without Diamond):** ```cpp #include using namespace std; @@ -285,8 +272,7 @@ public: } }; -// Multilevel extension: WorkingStudent inherits only from Student -// This combines Multilevel with the Hierarchical design without forming a diamond. +// Multilevel + Hierarchical class WorkingStudent : public Student { public: void partTimeJob() { @@ -299,19 +285,16 @@ int main() { ws.introduce(); // From Person ws.study(); // From Student ws.partTimeJob(); // Own method - // ws.work(); // Not available – WorkingStudent is not an Employee. No ambiguity. - // Demonstrate independent Employee branch Employee emp; emp.introduce(); emp.work(); - + return 0; } ``` **Output:** - ```text I am a person. I am studying. @@ -320,60 +303,47 @@ I am a person. I am working. ``` +## 7. Diamond Problem and Virtual Inheritance -## 7. Diamond Problem -The Diamond Problem occurs when two classes (say `B` and `C`) inherit from a common base class `A`, and a class `D` inherits from both `B` and `C`. This creates an ambiguous diamond‑shaped hierarchy: +The Diamond Problem occurs in multiple inheritance when two classes inherit from a common base, and another class inherits from both, leading to ambiguity and duplication. +**Diagram:** ```mermaid graph TD A[Class A] B[Class B] C[Class C] D[Class D] - B --> A C --> A D --> B D --> C ``` -**Example:** - +**Example without Virtual:** ```cpp #include using namespace std; -// Base class class A { public: void show() { cout << "Class A" << endl; } }; -// Derived from A (Hierarchical) class B : public A {}; - -// Derived from A (Hierarchical) class C : public A {}; - -// Derived from both B and C (Multiple) class D : public B, public C {}; int main() { D obj; - // obj.show(); // ERROR: ambiguous! Which path? B::A::show or C::A::show? - obj.B::show(); // Calling through B's copy - obj.C::show(); // Calling through C's copy + // obj.show(); // Ambiguous! + obj.B::show(); // Explicit resolution + obj.C::show(); return 0; } ``` -**Problems:** -- Ambiguity: Which base class sub‑object should D use when a member of A is referenced? -- Duplication: D contains two separate copies of A’s members, wasting memory and creating inconsistency. - **Solution: Virtual Inheritance** -Using the virtual keyword while inheriting ensures that only one shared copy of the base class is created, no matter how many paths lead to it. - ```cpp #include using namespace std; @@ -385,25 +355,20 @@ public: } }; -// Virtual inheritance class B : virtual public A {}; class C : virtual public A {}; - class D : public B, public C {}; int main() { D obj; - obj.show(); // No ambiguity, single copy of A + obj.show(); // No ambiguity return 0; } ``` **Output:** - ```text Class A ``` -**How it works:** -Virtual inheritance tells the compiler to share the base class sub‑object among all virtually derived classes. The most‑derived class (`D`) is then responsible for constructing the shared base class (`A`) directly. -While virtual inheritance solves the diamond problem, it may introduce minor performance overhead and complexity. It should be used only when a true diamond hierarchy exists and shared state is required. +Virtual inheritance ensures a single shared instance of the base class, solving duplication and ambiguity. Use it judiciously due to added complexity. \ No newline at end of file diff --git a/docs/programming-fundamentals/oop-basics/methods.md b/docs/programming-fundamentals/oop-basics/methods.md new file mode 100644 index 000000000..ca1331a09 --- /dev/null +++ b/docs/programming-fundamentals/oop-basics/methods.md @@ -0,0 +1,274 @@ +--- +id: methods +title: "Methods" +sidebar_label: "Methods" +sidebar_position: 7 +description: "Comprehensive guide to methods in C++: declaration, invocation, parameters, return types, instance vs static, and best practices." +tags: [Methods, Functions, OOP, C++, Best-Practices] +--- + +# Methods in C++ + +In C++, methods (also called member functions) are functions defined inside a class. They define the behavior of objects and are central to Object-Oriented Programming. + +## 1. Introduction to Methods + +**Definition:** +A method is a function associated with a class or object. It can access and modify the data members of the class. + +**Key Benefits:** +- Encapsulation: Methods control access to data. +- Code Reusability: Common operations are defined once. +- Abstraction: Hide implementation details. + +**Syntax:** +```cpp +class ClassName { +public: + returnType methodName(parameters) { + // method body + } +}; +``` + +## 2. Method Declaration and Invocation + +### Declaration +Methods are declared inside the class definition. + +```cpp +class Calculator { +public: + // Declaration + int add(int a, int b); +}; +``` + +### Definition (Implementation) +Can be inside the class (inline) or outside using scope resolution operator `::`. + +**Inside class:** +```cpp +class Calculator { +public: + int add(int a, int b) { + return a + b; + } +}; +``` + +**Outside class:** +```cpp +class Calculator { +public: + int add(int a, int b); +}; + +int Calculator::add(int a, int b) { + return a + b; +} +``` + +### Invocation +Call methods using the dot (`.`) operator on objects. + +```cpp +#include +using namespace std; + +int main() { + Calculator calc; + int result = calc.add(5, 3); // Invocation + cout << "Sum: " << result << endl; + return 0; +} +``` + +**Output:** +```text +Sum: 8 +``` + +## 3. Parameters and Return Types + +### Parameters +- **Formal Parameters:** Declared in method signature. +- **Actual Parameters:** Passed during invocation. +- Can be passed by value, by reference (`&`), or by pointer (`*`). + +**Example:** +```cpp +class MathUtils { +public: + // Pass by value + int square(int num) { + return num * num; + } + + // Pass by reference + void swap(int &a, int &b) { + int temp = a; + a = b; + b = temp; + } +}; +``` + +### Return Types +- Any valid C++ type: `void`, `int`, `double`, custom objects, references, pointers, etc. +- Use `void` for methods that don't return a value. + +**Example with different return types:** +```cpp +#include +#include +using namespace std; + +class Person { + string name; +public: + // No return (void) + void setName(string n) { + name = n; + } + + // Return primitive + int getAge() { + return 25; + } + + // Return object/reference + string getName() { + return name; + } +}; +``` + +## 4. Instance vs Static Methods + +### Instance Methods +- Belong to objects (instances) of the class. +- Can access both instance and static members. +- Called using object. + +```cpp +class Counter { + int count = 0; +public: + // Instance method + void increment() { + count++; + } + + int getCount() { + return count; + } +}; + +int main() { + Counter c1, c2; + c1.increment(); + cout << c1.getCount() << endl; // 1 + return 0; +} +``` + +### Static Methods +- Belong to the class itself. +- Cannot access non-static (instance) members. +- Called using class name. +- Useful for utility functions. + +```cpp +#include +using namespace std; + +class Math { +public: + // Static method + static int add(int a, int b) { + return a + b; + } + + static const double PI; +}; + +const double Math::PI = 3.14159; + +int main() { + cout << Math::add(10, 20) << endl; // 30 + cout << Math::PI << endl; + return 0; +} +``` + +**Key Differences:** + +| Feature | Instance Method | Static Method | +|--------------------------|----------------------------------|-----------------------------------| +| Access | Object (`.`) | Class (`::`) | +| Can access instance data | Yes | No | +| Can access static data | Yes | Yes | +| `this` pointer | Available | Not available | +| Use case | Object-specific behavior | Utility / class-level operations | + +## 5. Method Design Best Practices + +1. **Single Responsibility Principle** + Each method should do one thing well. + +2. **Meaningful Names** + Use verbs for methods: `calculateTotal()`, `validateInput()`. + +3. **Parameter Limits** + Keep number of parameters low (ideally ≤ 4). Use objects/structs for many parameters. + +4. **Const Correctness** + Use `const` for methods that don't modify object state. + ```cpp + int getValue() const { return value; } + ``` + +5. **Avoid Global/State Dependencies** + Prefer pure functions where possible. + +6. **Error Handling** + Use exceptions or return error codes appropriately. + +7. **Overloading** + Methods can be overloaded with different parameters. + ```cpp + class Printer { + public: + void print(int n); + void print(double d); + void print(string s); + }; + ``` + +8. **Default Arguments** + Provide sensible defaults. + ```cpp + void log(string message, int level = 1); + ``` + +9. **Inline vs Out-of-line** + Define small methods inside class for better performance (inlining). + +10. **Documentation** + Always add comments describing purpose, parameters, and return value. + +## 6. Advanced Topics + +### Method Overriding (in Inheritance) +Covered in Inheritance documentation. Use `virtual` for polymorphic behavior. + +### Const Member Functions +Prevent accidental modification of object state. + +### Friend Functions +Non-member functions granted access to private members. + +--- + +**Following these guidelines will help you write clean, maintainable, and efficient methods in your C++ programs.** \ No newline at end of file diff --git a/docs/programming-fundamentals/oop-basics/modifiers.md b/docs/programming-fundamentals/oop-basics/modifiers.md new file mode 100644 index 000000000..e58f7cbf5 --- /dev/null +++ b/docs/programming-fundamentals/oop-basics/modifiers.md @@ -0,0 +1,170 @@ +--- +id: access-modifiers +title: "Access Modifiers" +sidebar_label: "Access Modifiers" +sidebar_position: 7 +description: "Complete guide to public, private, and protected access modifiers in C++, encapsulation, friend functions, and best practices." +tags: [Access-Modifiers, Public, Private, Protected, Encapsulation, OOP, Friend] +--- + +# Access Modifiers in C++ + +Access modifiers control the **visibility** and **accessibility** of class members, forming the foundation of **encapsulation** in OOP. + +--- + +## 1. Introduction + +C++ provides three access specifiers: +- `public` +- `protected` +- `private` + +**Default Behavior:** +- `class` → members are `private` by default +- `struct` → members are `public` by default + +--- + +## 2. Public + +Accessible from **anywhere**. + +**Example:** +```cpp +#include +using namespace std; + +class Student { +public: + string name; + + void display() { + cout << "Name: " << name << endl; + } +}; + +int main() { + Student s; + s.name = "Alice"; + s.display(); + return 0; +} +``` + +--- + +## 3. Private + +Accessible **only within the same class**. + +**Example:** +```cpp +#include +using namespace std; + +class BankAccount { +private: + double balance; + +public: + BankAccount(double initial) : balance(initial) {} + + void deposit(double amount) { + if (amount > 0) balance += amount; + } + + double getBalance() const { + return balance; + } +}; + +int main() { + BankAccount acc(1000); + acc.deposit(500); + cout << "Balance: " << acc.getBalance() << endl; + return 0; +} +``` + +--- + +## 4. Protected + +Accessible within the class and **derived classes**. + +**Example:** +```cpp +#include +using namespace std; + +class Vehicle { +protected: + int speed = 0; + +public: + void accelerate(int inc) { speed += inc; } +}; + +class Car : public Vehicle { +public: + void showSpeed() { + cout << "Speed: " << speed << " km/h\n"; + } +}; + +int main() { + Car c; + c.accelerate(80); + c.showSpeed(); + return 0; +} +``` + +--- + +## 5. Summary Table + +| Specifier | Same Class | Derived Class | Outside Class | +|-------------|------------|---------------|---------------| +| `public` | Yes | Yes | Yes | +| `protected` | Yes | Yes | No | +| `private` | Yes | No | No | + +--- + +## 6. Friend Functions & Classes + +`friend` keyword bypasses access rules. + +```cpp +class Box { +private: + int length; + +public: + friend void printLength(Box b); +}; + +void printLength(Box b) { + cout << "Length: " << b.length << endl; +} +``` + +--- + +## 7. Relationship with Inheritance + +Access modifiers affect how base class members are inherited (see Inheritance documentation). + +--- + +## 8. Best Practices + +1. Make data members `private` by default. +2. Provide public getters/setters or methods. +3. Use `protected` only when needed for inheritance. +4. Minimize use of `friend`. +5. Follow const-correctness. + +These two files are now ready for download. \ No newline at end of file