fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <initializer_list>
  5. #include <utility>
  6.  
  7. using namespace std;
  8.  
  9. /*
  10.   ============================================================
  11.   SHALLOW COPY VS DEEP COPY
  12.   ============================================================
  13.  
  14.   Shallow Copy:
  15.   - Copies the pointer address only.
  16.   - The original object and copied object share the same memory.
  17.   - Changing data through one object affects the other object.
  18.   - Dangerous with destructors because both objects may try to delete
  19.   the same memory.
  20.  
  21.   Deep Copy:
  22.   - Allocates new memory for the copied object.
  23.   - Copies the actual values from the original object.
  24.   - Each object owns its own separate memory.
  25.   - Changing one object does not affect the other object.
  26. */
  27.  
  28. /*
  29.   ============================================================
  30.   1) SHALLOW COPY EXAMPLE
  31.   ============================================================
  32. */
  33.  
  34. class ShallowArray {
  35. private:
  36. int* data;
  37. int size;
  38.  
  39. public:
  40. /*
  41.   Parameterized Constructor
  42.  
  43.   Syntax:
  44.   ClassName(parameters)
  45.  
  46.   Purpose:
  47.   - Creates an object using given arguments.
  48.   - Here, it receives the array size and allocates memory.
  49.   */
  50. ShallowArray(int s) {
  51. size = s;
  52. data = new int[size];
  53.  
  54. for (int i = 0; i < size; i++) {
  55. data[i] = 0;
  56. }
  57. }
  58.  
  59. /*
  60.   Shallow Copy Constructor
  61.  
  62.   Syntax:
  63.   ClassName(const ClassName& other)
  64.  
  65.   Purpose:
  66.   - Creates a new object from another existing object.
  67.  
  68.   Difference:
  69.   - This shallow copy constructor copies only the pointer address.
  70.   - It does NOT allocate a new array.
  71.   - Both objects point to the same memory.
  72.   */
  73. ShallowArray(const ShallowArray& other) {
  74. size = other.size;
  75. data = other.data;
  76. }
  77.  
  78. void setValue(int index, int value) {
  79. data[index] = value;
  80. }
  81.  
  82. void print() const {
  83. for (int i = 0; i < size; i++) {
  84. cout << data[i] << " ";
  85. }
  86.  
  87. cout << endl;
  88. }
  89.  
  90. /*
  91.   Important Note:
  92.  
  93.   We do not write a destructor here intentionally.
  94.  
  95.   If we write:
  96.   delete[] data;
  97.  
  98.   then both objects will try to delete the same memory because
  99.   shallow copy makes them share the same pointer.
  100.  
  101.   This may cause double delete, which is undefined behavior.
  102.   */
  103. };
  104.  
  105. /*
  106.   ============================================================
  107.   2) DEEP COPY EXAMPLE
  108.   ============================================================
  109. */
  110.  
  111. class DeepArray {
  112. private:
  113. int* data;
  114. int size;
  115.  
  116. public:
  117. /*
  118.   Default Constructor
  119.  
  120.   Syntax:
  121.   ClassName()
  122.  
  123.   Purpose:
  124.   - Creates an object without receiving arguments.
  125.   - Here, it creates an empty array object.
  126.   */
  127. DeepArray() {
  128. size = 0;
  129. data = nullptr;
  130. }
  131.  
  132. /*
  133.   Parameterized Constructor
  134.  
  135.   Syntax:
  136.   ClassName(parameters)
  137.  
  138.   Purpose:
  139.   - Creates an object using arguments.
  140.   - Here, it receives the array size and allocates memory.
  141.   */
  142. DeepArray(int s) {
  143. size = s;
  144. data = new int[size];
  145.  
  146. for (int i = 0; i < size; i++) {
  147. data[i] = 0;
  148. }
  149. }
  150.  
  151. /*
  152.   Deep Copy Constructor
  153.  
  154.   Syntax:
  155.   ClassName(const ClassName& other)
  156.  
  157.   Purpose:
  158.   - Creates a new object from another existing object.
  159.  
  160.   Difference:
  161.   - This deep copy constructor allocates new memory.
  162.   - Then it copies the actual values.
  163.   - Each object has its own independent array.
  164.   */
  165. DeepArray(const DeepArray& other) {
  166. size = other.size;
  167. data = new int[size];
  168.  
  169. for (int i = 0; i < size; i++) {
  170. data[i] = other.data[i];
  171. }
  172. }
  173.  
  174. /*
  175.   Copy Assignment Operator
  176.  
  177.   Syntax:
  178.   ClassName& operator=(const ClassName& other)
  179.  
  180.   Purpose:
  181.   - Used when assigning one existing object to another existing object.
  182.  
  183.   Example:
  184.   DeepArray a(3);
  185.   DeepArray b(5);
  186.   b = a;
  187.  
  188.   Difference from Copy Constructor:
  189.   - Copy constructor creates a new object.
  190.   - Copy assignment modifies an already existing object.
  191.   */
  192. DeepArray& operator=(const DeepArray& other) {
  193. if (this == &other) {
  194. return *this;
  195. }
  196.  
  197. delete[] data;
  198.  
  199. size = other.size;
  200. data = new int[size];
  201.  
  202. for (int i = 0; i < size; i++) {
  203. data[i] = other.data[i];
  204. }
  205.  
  206. return *this;
  207. }
  208.  
  209. /*
  210.   Move Constructor
  211.  
  212.   Syntax:
  213.   ClassName(ClassName&& other)
  214.  
  215.   Purpose:
  216.   - Creates a new object by taking resources from another object.
  217.   - Usually used with temporary objects or std::move.
  218.  
  219.   Difference from Copy Constructor:
  220.   - Copy constructor duplicates the resource.
  221.   - Move constructor transfers ownership of the resource.
  222.   - It is usually faster for dynamic memory or containers.
  223.   */
  224. DeepArray(DeepArray&& other) noexcept {
  225. size = other.size;
  226. data = other.data;
  227.  
  228. other.size = 0;
  229. other.data = nullptr;
  230. }
  231.  
  232. /*
  233.   Move Assignment Operator
  234.  
  235.   Syntax:
  236.   ClassName& operator=(ClassName&& other)
  237.  
  238.   Purpose:
  239.   - Transfers resources from one object to another existing object.
  240.  
  241.   Difference from Move Constructor:
  242.   - Move constructor creates a new object.
  243.   - Move assignment modifies an already existing object.
  244.   */
  245. DeepArray& operator=(DeepArray&& other) noexcept {
  246. if (this == &other) {
  247. return *this;
  248. }
  249.  
  250. delete[] data;
  251.  
  252. size = other.size;
  253. data = other.data;
  254.  
  255. other.size = 0;
  256. other.data = nullptr;
  257.  
  258. return *this;
  259. }
  260.  
  261. /*
  262.   Destructor
  263.  
  264.   Syntax:
  265.   ~ClassName()
  266.  
  267.   Purpose:
  268.   - Called automatically when the object is destroyed.
  269.   - Used here to free dynamic memory.
  270.  
  271.   Important:
  272.   - Destructor is not a constructor.
  273.   - But it is important when the class owns dynamic memory.
  274.   */
  275. ~DeepArray() {
  276. delete[] data;
  277. }
  278.  
  279. void setValue(int index, int value) {
  280. data[index] = value;
  281. }
  282.  
  283. void print() const {
  284. for (int i = 0; i < size; i++) {
  285. cout << data[i] << " ";
  286. }
  287.  
  288. cout << endl;
  289. }
  290. };
  291.  
  292. /*
  293.   ============================================================
  294.   3) CONSTRUCTORS EXAMPLES IN ONE CLASS
  295.   ============================================================
  296. */
  297.  
  298. class Student {
  299. private:
  300. string name;
  301. int age;
  302. const int id;
  303. int& mark;
  304. vector<int> grades;
  305.  
  306. /*
  307.   This helper function returns a reference to a static integer.
  308.  
  309.   Why do we need it?
  310.   - The class has a reference data member: int& mark.
  311.   - A reference must always refer to a valid variable.
  312.   - Some constructors do not receive a mark variable.
  313.   - So we use this dummy variable for those constructors.
  314.   */
  315. static int& dummyMark() {
  316. static int value = 0;
  317. return value;
  318. }
  319.  
  320. public:
  321. /*
  322.   Default Constructor
  323.  
  324.   Syntax:
  325.   ClassName()
  326.  
  327.   Example:
  328.   Student s;
  329.  
  330.   Purpose:
  331.   - Creates an object without arguments.
  332.  
  333.   Difference:
  334.   - It does not receive values from the caller.
  335.   - It uses default values written inside the constructor.
  336.   */
  337. Student()
  338. : name("Unknown"),
  339. age(0),
  340. id(0),
  341. mark(dummyMark()) {
  342. cout << "Default constructor called\n";
  343. }
  344.  
  345. /*
  346.   Parameterized Constructor
  347.  
  348.   Syntax:
  349.   ClassName(type parameter1, type parameter2, ...)
  350.  
  351.   Example:
  352.   Student s("Ali", 20, 1001, mark);
  353.  
  354.   Purpose:
  355.   - Creates an object using values sent by the caller.
  356.  
  357.   Difference:
  358.   - Unlike the default constructor, it receives arguments.
  359.   */
  360. Student(string n, int a, int studentId, int& m)
  361. : name(n),
  362. age(a),
  363. id(studentId),
  364. mark(m) {
  365. cout << "Parameterized constructor called\n";
  366. }
  367.  
  368. /*
  369.   Constructor With Default Arguments
  370.  
  371.   Syntax:
  372.   ClassName(type parameter1, type parameter2 = defaultValue)
  373.  
  374.   Examples:
  375.   Student s1("Mona");
  376.   Student s2("Omar", 22);
  377.  
  378.   Purpose:
  379.   - Allows calling the same constructor with fewer arguments.
  380.  
  381.   Difference:
  382.   - If the caller does not provide the second argument,
  383.   the default value is used.
  384.   */
  385. Student(string n, int a = 18)
  386. : name(n),
  387. age(a),
  388. id(-1),
  389. mark(dummyMark()) {
  390. cout << "Constructor with default arguments called\n";
  391. }
  392.  
  393. /*
  394.   initializer_list Constructor
  395.  
  396.   Syntax:
  397.   ClassName(initializer_list<type> list)
  398.  
  399.   Example:
  400.   Student s{90, 80, 70};
  401.  
  402.   Purpose:
  403.   - Allows creating an object using a list of values inside braces.
  404.  
  405.   Difference:
  406.   - This is useful when the number of input values may vary.
  407.   - It is different from member initializer list.
  408.   */
  409. Student(initializer_list<int> g)
  410. : name("Grades Student"),
  411. age(0),
  412. id(-2),
  413. mark(dummyMark()),
  414. grades(g) {
  415. cout << "initializer_list constructor called\n";
  416. }
  417.  
  418. /*
  419.   Copy Constructor
  420.  
  421.   Syntax:
  422.   ClassName(const ClassName& other)
  423.  
  424.   Examples:
  425.   Student s2 = s1;
  426.   Student s3(s1);
  427.  
  428.   Purpose:
  429.   - Creates a new object as a copy of an existing object.
  430.  
  431.   Difference:
  432.   - It is called when a new object is being created from
  433.   another object of the same class.
  434.   */
  435. Student(const Student& other)
  436. : name(other.name),
  437. age(other.age),
  438. id(other.id),
  439. mark(other.mark),
  440. grades(other.grades) {
  441. cout << "Copy constructor called\n";
  442. }
  443.  
  444. /*
  445.   Move Constructor
  446.  
  447.   Syntax:
  448.   ClassName(ClassName&& other)
  449.  
  450.   Example:
  451.   Student s2 = std::move(s1);
  452.  
  453.   Purpose:
  454.   - Creates a new object by moving resources from another object.
  455.  
  456.   Difference:
  457.   - It can avoid expensive copying.
  458.   - It is especially useful with strings, vectors, dynamic memory,
  459.   and temporary objects.
  460.   */
  461. Student(Student&& other) noexcept
  462. : name(std::move(other.name)),
  463. age(other.age),
  464. id(other.id),
  465. mark(other.mark),
  466. grades(std::move(other.grades)) {
  467. cout << "Move constructor called\n";
  468.  
  469. other.age = 0;
  470. }
  471.  
  472. /*
  473.   Conversion Constructor
  474.  
  475.   Syntax:
  476.   ClassName(singleParameter)
  477.  
  478.   Example:
  479.   Student s = 25;
  480.  
  481.   Purpose:
  482.   - Allows converting another type into this class type.
  483.  
  484.   Difference:
  485.   - Because it has one parameter and is not explicit,
  486.   implicit conversion is allowed.
  487.   */
  488. Student(int a)
  489. : name("Converted Student"),
  490. age(a),
  491. id(-3),
  492. mark(dummyMark()) {
  493. cout << "Conversion constructor called\n";
  494. }
  495.  
  496. /*
  497.   Delegating Constructor
  498.  
  499.   Syntax:
  500.   ClassName(parameters) : ClassName(otherArguments)
  501.  
  502.   Example:
  503.   Student s('A');
  504.  
  505.   Purpose:
  506.   - Allows one constructor to call another constructor
  507.   in the same class.
  508.  
  509.   Difference:
  510.   - Reduces repeated initialization code.
  511.   */
  512. Student(char gradeLetter)
  513. : Student(string("Grade ") + gradeLetter, 18) {
  514. cout << "Delegating constructor called\n";
  515. }
  516.  
  517. /*
  518.   Member Initializer List
  519.  
  520.   Syntax:
  521.   Constructor(parameters) : member1(value1), member2(value2)
  522.  
  523.   Purpose:
  524.   - Initializes members before entering the constructor body.
  525.  
  526.   Difference:
  527.   - This is not a constructor type by itself.
  528.   - It is a constructor syntax.
  529.   - It is required for const members and reference members.
  530.   - It is usually better than assigning values inside the body.
  531.   */
  532.  
  533. /*
  534.   Destructor
  535.  
  536.   Syntax:
  537.   ~ClassName()
  538.  
  539.   Purpose:
  540.   - Called automatically when an object is destroyed.
  541.  
  542.   Difference:
  543.   - It is not a constructor.
  544.   - It cleans up instead of creating the object.
  545.   */
  546. ~Student() {
  547. cout << "Destructor called for " << name << endl;
  548. }
  549.  
  550. void print() const {
  551. cout << "Name: " << name << endl;
  552. cout << "Age: " << age << endl;
  553. cout << "ID: " << id << endl;
  554. cout << "Mark: " << mark << endl;
  555.  
  556. if (!grades.empty()) {
  557. cout << "Grades: ";
  558.  
  559. for (int grade : grades) {
  560. cout << grade << " ";
  561. }
  562.  
  563. cout << endl;
  564. }
  565.  
  566. cout << "-------------------------\n";
  567. }
  568. };
  569.  
  570. /*
  571.   ============================================================
  572.   4) EXPLICIT CONSTRUCTOR EXAMPLE
  573.   ============================================================
  574. */
  575.  
  576. class ExplicitExample {
  577. private:
  578. int value;
  579.  
  580. public:
  581. /*
  582.   Explicit Constructor
  583.  
  584.   Syntax:
  585.   explicit ClassName(type parameter)
  586.  
  587.   Examples:
  588.   ExplicitExample e1(10);
  589.   ExplicitExample e2{20};
  590.  
  591.   Purpose:
  592.   - Prevents implicit conversion.
  593.  
  594.   Difference from Conversion Constructor:
  595.   - Conversion constructor allows:
  596.   ExplicitExample e = 10;
  597.   - Explicit constructor prevents that.
  598.   */
  599. explicit ExplicitExample(int v) {
  600. value = v;
  601. cout << "Explicit constructor called\n";
  602. }
  603.  
  604. void print() const {
  605. cout << "Value: " << value << endl;
  606. }
  607. };
  608.  
  609. /*
  610.   ============================================================
  611.   5) PRIVATE CONSTRUCTOR EXAMPLE
  612.   ============================================================
  613. */
  614.  
  615. class Logger {
  616. private:
  617. /*
  618.   Private Constructor
  619.  
  620.   Syntax:
  621.   private:
  622.   ClassName()
  623.  
  624.   Purpose:
  625.   - Prevents creating objects directly from outside the class.
  626.  
  627.   Difference:
  628.   - Normal public constructors can be called from outside.
  629.   - Private constructors can only be called from inside the class.
  630.   */
  631. Logger() {
  632. cout << "Private constructor called\n";
  633. }
  634.  
  635. public:
  636. /*
  637.   Static function used to access the single Logger object.
  638.  
  639.   This is a simple Singleton-style example.
  640.   */
  641. static Logger& getInstance() {
  642. static Logger instance;
  643. return instance;
  644. }
  645.  
  646. void log(const string& message) {
  647. cout << "LOG: " << message << endl;
  648. }
  649. };
  650.  
  651. /*
  652.   ============================================================
  653.   6) DEFAULTED AND DELETED CONSTRUCTORS EXAMPLE
  654.   ============================================================
  655. */
  656.  
  657. class ConstructorControl {
  658. private:
  659. int value = 0;
  660.  
  661. public:
  662. /*
  663.   Defaulted Constructor
  664.  
  665.   Syntax:
  666.   ClassName() = default;
  667.  
  668.   Purpose:
  669.   - Asks the compiler to generate the default constructor.
  670.  
  671.   Difference:
  672.   - Useful when you want compiler-generated behavior explicitly.
  673.   */
  674. ConstructorControl() = default;
  675.  
  676. /*
  677.   Parameterized Constructor
  678.   */
  679. ConstructorControl(int v) {
  680. value = v;
  681. cout << "ConstructorControl parameterized constructor called\n";
  682. }
  683.  
  684. /*
  685.   Deleted Copy Constructor
  686.  
  687.   Syntax:
  688.   ClassName(const ClassName& other) = delete;
  689.  
  690.   Purpose:
  691.   - Prevents copying objects of this class.
  692.  
  693.   Difference:
  694.   - If someone tries to copy, the code will not compile.
  695.   */
  696. ConstructorControl(const ConstructorControl& other) = delete;
  697.  
  698. void print() const {
  699. cout << "Value: " << value << endl;
  700. }
  701. };
  702.  
  703. /*
  704.   ============================================================
  705.   7) CONSTEXPR CONSTRUCTOR EXAMPLE
  706.   ============================================================
  707. */
  708.  
  709. class Point {
  710. private:
  711. int x;
  712. int y;
  713.  
  714. public:
  715. /*
  716.   constexpr Constructor
  717.  
  718.   Syntax:
  719.   constexpr ClassName(parameters)
  720.  
  721.   Purpose:
  722.   - Allows creating objects that can be evaluated at compile time.
  723.  
  724.   Difference:
  725.   - Useful for constant objects and compile-time calculations.
  726.   */
  727. constexpr Point(int xValue, int yValue)
  728. : x(xValue),
  729. y(yValue) {
  730. }
  731.  
  732. constexpr int getX() const {
  733. return x;
  734. }
  735.  
  736. constexpr int getY() const {
  737. return y;
  738. }
  739. };
  740.  
  741. /*
  742.   ============================================================
  743.   MAIN FUNCTION
  744.   ============================================================
  745. */
  746.  
  747. int main() {
  748. cout << "================ SHALLOW COPY ================\n";
  749.  
  750. ShallowArray shallow1(3);
  751.  
  752. shallow1.setValue(0, 10);
  753. shallow1.setValue(1, 20);
  754. shallow1.setValue(2, 30);
  755.  
  756. /*
  757.   This calls the shallow copy constructor.
  758.  
  759.   Both shallow1 and shallow2 will share the same array.
  760.   */
  761. ShallowArray shallow2 = shallow1;
  762.  
  763. cout << "shallow1 before change: ";
  764. shallow1.print();
  765.  
  766. cout << "shallow2 before change: ";
  767. shallow2.print();
  768.  
  769. shallow2.setValue(0, 999);
  770.  
  771. cout << "shallow1 after changing shallow2: ";
  772. shallow1.print();
  773.  
  774. cout << "shallow2 after changing shallow2: ";
  775. shallow2.print();
  776.  
  777. cout << "\n";
  778.  
  779. cout << "================ DEEP COPY ================\n";
  780.  
  781. DeepArray deep1(3);
  782.  
  783. deep1.setValue(0, 10);
  784. deep1.setValue(1, 20);
  785. deep1.setValue(2, 30);
  786.  
  787. /*
  788.   This calls the deep copy constructor.
  789.  
  790.   deep1 and deep2 will have separate arrays.
  791.   */
  792. DeepArray deep2 = deep1;
  793.  
  794. cout << "deep1 before change: ";
  795. deep1.print();
  796.  
  797. cout << "deep2 before change: ";
  798. deep2.print();
  799.  
  800. deep2.setValue(0, 999);
  801.  
  802. cout << "deep1 after changing deep2: ";
  803. deep1.print();
  804.  
  805. cout << "deep2 after changing deep2: ";
  806. deep2.print();
  807.  
  808. cout << "\n";
  809.  
  810. cout << "================ COPY ASSIGNMENT ================\n";
  811.  
  812. DeepArray deep3(2);
  813.  
  814. deep3.setValue(0, 7);
  815. deep3.setValue(1, 8);
  816.  
  817. cout << "deep3 before assignment: ";
  818. deep3.print();
  819.  
  820. /*
  821.   This calls the copy assignment operator, not the copy constructor.
  822.  
  823.   deep3 already exists, so assignment is used.
  824.   */
  825. deep3 = deep2;
  826.  
  827. cout << "deep3 after assignment from deep2: ";
  828. deep3.print();
  829.  
  830. cout << "\n";
  831.  
  832. cout << "================ MOVE CONSTRUCTOR ================\n";
  833.  
  834. /*
  835.   This calls the move constructor.
  836.  
  837.   deep3 gives its internal array to deep4.
  838.   */
  839. DeepArray deep4 = std::move(deep3);
  840.  
  841. cout << "deep4 after move: ";
  842. deep4.print();
  843.  
  844. cout << "\n";
  845.  
  846. cout << "================ MOVE ASSIGNMENT ================\n";
  847.  
  848. DeepArray deep5(1);
  849. deep5.setValue(0, 555);
  850.  
  851. /*
  852.   This calls the move assignment operator.
  853.  
  854.   deep5 already exists, so move assignment is used.
  855.   */
  856. deep5 = std::move(deep4);
  857.  
  858. cout << "deep5 after move assignment: ";
  859. deep5.print();
  860.  
  861. cout << "\n";
  862.  
  863. cout << "================ STUDENT CONSTRUCTORS ================\n";
  864.  
  865. int mark = 95;
  866.  
  867. /*
  868.   Default constructor
  869.   */
  870. Student s1;
  871. s1.print();
  872.  
  873. /*
  874.   Parameterized constructor
  875.   */
  876. Student s2("Ali", 20, 1001, mark);
  877. s2.print();
  878.  
  879. /*
  880.   Constructor with default arguments
  881.  
  882.   The age is not passed, so it uses the default value 18.
  883.   */
  884. Student s3("Mona");
  885. s3.print();
  886.  
  887. /*
  888.   Constructor with default arguments
  889.  
  890.   The age is passed explicitly.
  891.   */
  892. Student s4("Omar", 22);
  893. s4.print();
  894.  
  895. /*
  896.   initializer_list constructor
  897.   */
  898. Student s5{90, 80, 70};
  899. s5.print();
  900.  
  901. /*
  902.   Copy constructor
  903.   */
  904. Student s6 = s2;
  905. s6.print();
  906.  
  907. /*
  908.   Move constructor
  909.   */
  910. Student s7 = std::move(s3);
  911. s7.print();
  912.  
  913. /*
  914.   Conversion constructor
  915.  
  916.   The integer 25 is converted into a Student object.
  917.   */
  918. Student s8 = 25;
  919. s8.print();
  920.  
  921. /*
  922.   Delegating constructor
  923.  
  924.   The char constructor calls another constructor.
  925.   */
  926. Student s9('A');
  927. s9.print();
  928.  
  929. cout << "\n";
  930.  
  931. cout << "================ EXPLICIT CONSTRUCTOR ================\n";
  932.  
  933. /*
  934.   Direct initialization is allowed.
  935.   */
  936. ExplicitExample e1(10);
  937. e1.print();
  938.  
  939. /*
  940.   Brace initialization is allowed.
  941.   */
  942. ExplicitExample e2{20};
  943. e2.print();
  944.  
  945. /*
  946.   Copy initialization is not allowed because the constructor is explicit.
  947.  
  948.   This line would cause a compilation error:
  949.  
  950.   ExplicitExample e3 = 30;
  951.   */
  952.  
  953. cout << "\n";
  954.  
  955. cout << "================ PRIVATE CONSTRUCTOR ================\n";
  956.  
  957. /*
  958.   Direct object creation is not allowed because the constructor is private.
  959.  
  960.   This line would cause a compilation error:
  961.  
  962.   Logger logger;
  963.   */
  964.  
  965. Logger& logger = Logger::getInstance();
  966. logger.log("This object was created using a private constructor.");
  967.  
  968. cout << "\n";
  969.  
  970. cout << "================ DEFAULTED AND DELETED CONSTRUCTORS ================\n";
  971.  
  972. /*
  973.   Defaulted constructor
  974.   */
  975. ConstructorControl c1;
  976. c1.print();
  977.  
  978. /*
  979.   Parameterized constructor
  980.   */
  981. ConstructorControl c2(50);
  982. c2.print();
  983.  
  984. /*
  985.   Copying is not allowed because the copy constructor is deleted.
  986.  
  987.   This line would cause a compilation error:
  988.  
  989.   ConstructorControl c3 = c2;
  990.   */
  991.  
  992. cout << "\n";
  993.  
  994. cout << "================ CONSTEXPR CONSTRUCTOR ================\n";
  995.  
  996. /*
  997.   This object can be created at compile time.
  998.   */
  999. constexpr Point p(3, 4);
  1000.  
  1001. cout << "Point x = " << p.getX() << endl;
  1002. cout << "Point y = " << p.getY() << endl;
  1003.  
  1004. cout << "\n";
  1005.  
  1006. return 0;
  1007. }
Success #stdin #stdout 0s 5320KB
stdin
Standard input is empty
stdout
================ SHALLOW COPY ================
shallow1 before change: 10 20 30 
shallow2 before change: 10 20 30 
shallow1 after changing shallow2: 999 20 30 
shallow2 after changing shallow2: 999 20 30 

================ DEEP COPY ================
deep1 before change: 10 20 30 
deep2 before change: 10 20 30 
deep1 after changing deep2: 10 20 30 
deep2 after changing deep2: 999 20 30 

================ COPY ASSIGNMENT ================
deep3 before assignment: 7 8 
deep3 after assignment from deep2: 999 20 30 

================ MOVE CONSTRUCTOR ================
deep4 after move: 999 20 30 

================ MOVE ASSIGNMENT ================
deep5 after move assignment: 999 20 30 

================ STUDENT CONSTRUCTORS ================
Default constructor called
Name: Unknown
Age: 0
ID: 0
Mark: 0
-------------------------
Parameterized constructor called
Name: Ali
Age: 20
ID: 1001
Mark: 95
-------------------------
Constructor with default arguments called
Name: Mona
Age: 18
ID: -1
Mark: 0
-------------------------
Constructor with default arguments called
Name: Omar
Age: 22
ID: -1
Mark: 0
-------------------------
initializer_list constructor called
Name: Grades Student
Age: 0
ID: -2
Mark: 0
Grades: 90 80 70 
-------------------------
Copy constructor called
Name: Ali
Age: 20
ID: 1001
Mark: 95
-------------------------
Move constructor called
Name: Mona
Age: 18
ID: -1
Mark: 0
-------------------------
Conversion constructor called
Name: Converted Student
Age: 25
ID: -3
Mark: 0
-------------------------
Constructor with default arguments called
Delegating constructor called
Name: Grade A
Age: 18
ID: -1
Mark: 0
-------------------------

================ EXPLICIT CONSTRUCTOR ================
Explicit constructor called
Value: 10
Explicit constructor called
Value: 20

================ PRIVATE CONSTRUCTOR ================
Private constructor called
LOG: This object was created using a private constructor.

================ DEFAULTED AND DELETED CONSTRUCTORS ================
Value: 0
ConstructorControl parameterized constructor called
Value: 50

================ CONSTEXPR CONSTRUCTOR ================
Point x = 3
Point y = 4

Destructor called for Grade A
Destructor called for Converted Student
Destructor called for Mona
Destructor called for Ali
Destructor called for Grades Student
Destructor called for Omar
Destructor called for 
Destructor called for Ali
Destructor called for Unknown