خلاصه استراکچر struct sumerize

Chapter 14: More About Classes

14.1 Instance and Static Members
  • Instance Variable: A member variable that is unique to each object created from a class. Each instance of a class has its own copy of an instance variable, storing data specific to that object.

  • Static Variable: A class-level variable shared among all instances of a class. There is only one copy of the static variable, regardless of how many objects are instantiated from the class, thus enabling counting or shared state across instances without needing to pass data through each object.

  • Static Member Function: A function that belongs to the class itself rather than to any particular object instance. Static member functions can be called without instantiating an object and can only access static member variables of the class.

Example: Static Member Variable
  • Tree Class Contents (Tree.h):

  - class Tree {

  - private:

  - static int objectCount; // Static member variable that tracks total number of Tree instances created

  - public:

  - Tree() { objectCount++; } // Constructor increments the count each time a new Tree object is instantiated

  - int getObjectCount() const { return objectCount; } // Accessor function to retrieve the current count of Tree instances

  - };

  • Definition of Static Member Variable:

      - int Tree::objectCount = 0; // Static member initialized outside the class definition

Program Example (Program 14-1)
  • ```

include

include "Tree.h"

using namespace std;

int main() {

    Tree oak;

    Tree elm;

    Tree pine;

    cout << "We have " << pine.getObjectCount() << " trees in our program!\n";

    return 0;

}

- **Program Output**: "We have 3 trees in our program!"  <br>
- **Key Concept**: Each instance of the `Tree` class (oak, elm, pine) shares a single `objectCount` variable, allowing the program to track the total number of `Tree` objects dynamically as they are created.

### 14.2 Friends of Classes
- **Friend**: A function or another class that, while not a member of a given class, has special access privileges to its private and protected members. This is often used to allow certain functions or classes to operate on data that would otherwise be encapsulated.
  - **Friend Function Declaration**: 
    - Stand-alone function: `friend void setAVal(int &val, int);` allows `setAVal` to modify private members of the class providing friendship.
    - Member function from another class: `friend void SomeClass::setNum(int num);` grants `SomeClass` access to private members.
- **Friend Class Declaration**:
  - Example: `class FriendClass {...};`
  - Main class defining friendship: `class NewClass { public: friend class FriendClass; };`  // Declares all members of `FriendClass` can access `NewClass`'s private members.

### 14.3 Memberwise Assignment
- Memberwise assignment permits the assignment of one object to another of the same class using the `=` operator. The contents of the object on the right side of the assignment are copied to the object on the left side.
  - Example: `instance2 = instance1;`  // Memberwise assignment that copies all non-static members of `instance1` into `instance2`.
  - At initialization: `Rectangle r2 = r1;`  // Initializes `r2` with values from `r1`.

### Program Example (Program 14-5)
- ```
#include <iostream>
#include "Rectangle.h"
using namespace std;

int main() {
    Rectangle box1(10.0, 10.0);
    Rectangle box2(20.0, 20.0);
    cout << "box1's width and length: " << box1.getWidth() << " " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << " " << box2.getLength() << endl;
    box2 = box1;  // Using memberwise assignment to copy dimensions from box1 to box2
    cout << "After assignment: box1's width and length: " << box1.getWidth() << " " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << " " << box2.getLength() << endl;
    return 0;
}
  • Program Output:

      - box1's width and length: 10 10

      - box2's width and length: 20 20

      - After assignment: box1's width and length: 10 10

      - box2's width and length: 10 10

14.4 Copy Constructors
  • Definition: A specialized constructor tasked with initializing a new object using the existing data of another object of the same class. This is particularly useful for classes that manage dynamic resources, ensuring correct resource allocation and ownership.

  • Default Copy Constructor: Automatically generated by the compiler, copying data member by member. This behavior is generally sufficient for classes without dynamic memory management.

Problem with Pointers
  • Issues can arise when objects contain pointers or dynamic members. For instance, if a class contains a pointer, a memberwise copy may result in multiple objects sharing the same memory, which can lead to undefined behavior.

  • Example of problematic dynamic memory management:
      - class SomeClass { public: SomeClass(int val = 0) { value = new int; *value = val; } ... }

Programmer-Defined Copy Constructor
  • Purpose: The programmer-defined copy constructor provides a way to allocate new memory for the new object, ensuring that it does not share pointers with the source object, thus avoiding data corruption or memory leaks.

  • Implementation:

      - SomeClass::SomeClass(const SomeClass &obj) { value = new int; *value = *obj.value; }

      - This code guarantees that each object instance maintains its own memory for value.

  • Use of const: Modify the copy constructor to accept a parameter as const SomeClass & to prevent unintended modifications to the object being copied.

Example of Class with Dynamic Memory (Contents of StudentTestScores.h)
  • ```
    class StudentTestScores {

    private:

        string studentName;

        double *testScores;

        int numTestScores;

    public:

       … // Functions for setting and getting scores, including a destructor for proper memory management.
    };

### 14.5 Operator Overloading
- **Definition**: Operators (such as `+`, `-`, `=`, etc.) can be redefined for custom class behaviors, allowing instances of classes to be manipulated using standard operators as if they were basic data types, enhancing code readability and usability.
- **Function Naming**: The overloaded operator functions must be preceded by the keyword `operator`, followed by the symbol being overloaded (e.g., `operator+`, `operator=`).

### The `this` Pointer
- **Understanding**: The `this` pointer is a special pointer within member functions, pointing to the instance of the class invoking the function. For example, in the statement `student1.getStudentName()`, `this` would refer to `student1`.
- **Behavior**: The `this` pointer is automatically passed as a hidden argument to all non-static member functions, enabling access to the instance's members.

### Overloaded Operator Invocation
- Operators can be invoked in two ways: as member functions or using their usual symbolic operation. 
  - Example as a member function: `object1.operator=(object2);`
  - Example of standard use: `object1 = object2;`  <br>

### Returning Values from Overloaded Operators
- Overloaded operators can return values similar to regular functions. For example, a class for representing two-dimensional points:
  - ```
class Point2d {
private:
    int x, y;
public:
    double operator-(const Point2d &right) {
        return sqrt(pow((x-right.x),2) + pow((y-right.y),2));
    }
};
  • Used in context: cout << point2 - point1; displays the distance computed between point1 and point2 based on the defined operator.

Notes on Operator Overloading
  • Operator overloading allows extending built-in operations to user-defined types but does not permit changing the number of operands or overloading certain operators (e.g., ?:, ., .*, ::, sizeof).

Rvalue References and Move Semantics
  • Rvalue References are utilized to handle temporary objects efficiently, particularly in classes that manage resources.

  • Understanding Rvalues and Lvalues:
        - Lvalues are named values that exist beyond their immediate creation context.
        - Rvalues are temporary and usually short-lived, created during expressions.

14.6 Object Conversion
  • Objects can automatically be converted into compatible types. However, for custom types, you need to define operator functions to facilitate these conversions, such as converting FeetInches to int accurately.

14.7 Aggregation
  • Definition: Aggregation is a design principle where one class contains references (or instances) of other classes, modeling the "has a" relationship. This promotes code reusability and modularity.

  • Example: class Student { private: StudentInfo personalData; ... }; Here, Student includes StudentInfo, representing that a student 'has' personal data.

14.10 Rvalue References and Move Semantics
  • Temporary Values are created during expression evaluations and exist briefly. Understanding these concepts is crucial for memory management, particularly in terms of performance and resource management when using dynamic data structures.

  • Distinction: Move constructors and move assignment operators should be distinct from copy constructors as they optimize resource handling by transferring ownership instead of duplicating resources, thus enhancing the overall performance of classes.