0% found this document useful (0 votes)
5 views

Scope Resolution in C++ (1)

The document explains the use of the scope resolution operator in C++, which helps access specific members from different scopes, resolve ambiguity, and organize code better. It also discusses the differences between shallow and deep copy, virtual functions, and the use of the const keyword in classes to maintain object integrity and prevent modifications. Each topic is illustrated with code examples to demonstrate the concepts effectively.

Uploaded by

Ajay Choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Scope Resolution in C++ (1)

The document explains the use of the scope resolution operator in C++, which helps access specific members from different scopes, resolve ambiguity, and organize code better. It also discusses the differences between shallow and deep copy, virtual functions, and the use of the const keyword in classes to maintain object integrity and prevent modifications. Each topic is illustrated with code examples to demonstrate the concepts effectively.

Uploaded by

Ajay Choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Scope Resolution in C++

what is use of scope resolution in oops in c++

The scope resolution operator (`::`) in C++ is used to access members (variables, functions, or classes)
that belong to a specific scope. It helps resolve ambiguity when multiple scopes have elements with the
same name.

Uses of Scope Resolution Operator (`::`) in OOPs (C++)

1. Access Global Variables When Shadowed

cpp

#include <iostream>
using namespace std;
int x = 10; // Global variable

class Test {
public:
int x = 20; // Member variable
void show() {
cout << "Local x: " << x << endl;
cout << "Global x: " << ::x << endl; // Accessing global x
}
};

int main() {
Test obj;
obj.show();
return 0;
}

Output:

sql

Local x: 20
Global x: 10

2. Define Class Member Functions Outside the Class

cpp

class Demo {
public:
void show(); // Function prototype
};

void Demo::show() { // Function definition outside class


cout << "Scope Resolution Operator Example" << endl;
}

int main() {
Demo obj;
obj.show();

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/13
return 0;
}

3. Access Static Class Members

cpp

class Sample {
public:
static int count;
};

int Sample::count = 100; // Initialize static variable outside the class

int main() {
cout << "Static count: " << Sample::count << endl;
return 0;
}

Output:

scss

Static count: 100

4. Access Base Class Members in Multiple Inheritance

cpp

class A {
public:
void show() { cout << "Class A" << endl; }
};

class B {
public:
void show() { cout << "Class B" << endl; }
};

class C : public A, public B {


public:
void display() {
A::show(); // Resolving ambiguity
B::show();
}
};

int main() {
C obj;
obj.display();
return 0;
}

Output:

css

Class A
Class B

5. Access Namespace Members

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 2/13
cpp

#include <iostream>
namespace ns {
int x = 50;
}

int main() {
cout << "Namespace x: " << ns::x << endl;
return 0;
}

Output:

vbnet

Namespace x: 50

Thus, the scope resolution operator (`::`) helps access specific elements across different scopes,
prevents ambiguity, and ensures better code organization.

difference between shallow copy and deep copy in c++

Difference Between Shallow Copy and Deep Copy in C++

Feature Shallow Copy Deep Copy


Copies object members as they are, Creates a new copy of dynamically allocated
Definition including pointers (only the memory memory (allocates new memory and copies
address is copied). actual values).
Memory The new object shares the same memory The new object gets separate memory for
Allocation for dynamically allocated members. dynamically allocated members.
Changes in copied object do not affect the
Impact on Changes in copied object affect the
original object (since a new copy of data is
Original Object original object (due to shared memory).
created).

Slower, as it allocates new memory and copies


Performance Faster, as only pointers are copied.
the data.
Used when an object does not contain Used when an object has dynamically allocated
Use Case
dynamically allocated memory. memory to avoid accidental modifications.
Causes issues like dangling pointers and
Avoids such issues by maintaining
Risk double deletion during object
independent copies.
destruction.

Example of Shallow Copy

cpp

#include <iostream>
using namespace std;

class Shallow {
public:

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 3/13
int* ptr;

// Constructor
Shallow(int val) {
ptr = new int(val);
}

// Default Copy Constructor (Shallow Copy)


Shallow(const Shallow& obj) {
ptr = obj.ptr; // Only copies the pointer address, not the actual value.
}

// Destructor
~Shallow() {
delete ptr; // May cause issues when multiple objects share the same pointer.
}
};

int main() {
Shallow obj1(10);
Shallow obj2 = obj1; // Shallow Copy

cout << "obj1: " << *obj1.ptr << endl;


cout << "obj2: " << *obj2.ptr << endl;

*obj2.ptr = 20; // Modifies obj1.ptr as well


cout << "After modification:" << endl;
cout << "obj1: " << *obj1.ptr << endl;
cout << "obj2: " << *obj2.ptr << endl;

return 0;
}

Output:

yaml

obj1: 10
obj2: 10
After modification:
obj1: 20
obj2: 20

🔴 Problem: Both `obj1` and `obj2` share the same memory. When one is modified, the other also gets
affected.

Example of Deep Copy

cpp

#include <iostream>
using namespace std;

class Deep {
public:
int* ptr;

// Constructor
Deep(int val) {
ptr = new int(val);
}

// Deep Copy Constructor


Deep(const Deep& obj) {
ptr = new int(*obj.ptr); // Creates a new copy of the data.
}

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 4/13
// Destructor
~Deep() {
delete ptr;
}
};

int main() {
Deep obj1(10);
Deep obj2 = obj1; // Deep Copy

cout << "obj1: " << *obj1.ptr << endl;


cout << "obj2: " << *obj2.ptr << endl;

*obj2.ptr = 20; // Changes only obj2


cout << "After modification:" << endl;
cout << "obj1: " << *obj1.ptr << endl;
cout << "obj2: " << *obj2.ptr << endl;

return 0;
}

Output:

yaml

obj1: 10
obj2: 10
After modification:
obj1: 10
obj2: 20

✅ Solution: Each object gets its own memory, preventing unintended modifications.
Conclusion

Use shallow copy when objects do not contain dynamically allocated memory.
Use deep copy when objects contain dynamically allocated memory to ensure each object has its
own copy.

For dynamically allocated objects, always implement deep copy to avoid dangling pointers and
memory leaks.

what are virtual functions expalin in detail

Virtual Functions in C++ (Detailed Explanation)

Definition:

A virtual function in C++ is a member function of a base class that can be overridden in a derived
class. It allows achieving runtime polymorphism, meaning the function that gets executed is
determined at runtime based on the actual type of the object, rather than the type of the
pointer/reference used to access it.

1. Why Use Virtual Functions?


Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/13
In normal function overriding, if a base class pointer points to a derived class object, the base class
version of the function is called instead of the derived class version. To override this behavior and call
the derived class function, virtual functions are used.

2. Example Without Virtual Function (Static Binding)


cpp

#include <iostream>
using namespace std;

class Base {
public:
void show() { // No virtual keyword
cout << "Base class show function" << endl;
}
};

class Derived : public Base {


public:
void show() {
cout << "Derived class show function" << endl;
}
};

int main() {
Base* ptr;
Derived obj;
ptr = &obj; // Base class pointer pointing to derived class object

ptr->show(); // Calls Base class function (Static Binding)


return 0;
}

Output:

pgsql

Base class show function

🔴 Problem: Even though `ptr` points to a `Derived` object, the base class function is called due to
static binding (compile-time binding).

3. Example With Virtual Function (Dynamic Binding)


cpp

#include <iostream>
using namespace std;

class Base {
public:
virtual void show() { // Virtual function
cout << "Base class show function" << endl;
}
};

class Derived : public Base {


public:
void show() override { // Overriding base class function
cout << "Derived class show function" << endl;

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/13
}
};

int main() {
Base* ptr;
Derived obj;
ptr = &obj;

ptr->show(); // Calls Derived class function (Dynamic Binding)


return 0;
}

Output:

pgsql

Derived class show function

✅ Solution: The virtual function ensures that the derived class function is called at runtime, not
the base class function.

4. Key Concepts of Virtual Functions


(a) Virtual Function Table (VTable) & VPointer (VPTR)

When a class has virtual functions:

1. The compiler creates a Virtual Table (VTable), which stores pointers to virtual functions.
2. Each object of the class gets a hidden VPTR (Virtual Pointer) that points to the VTable.
3. When a virtual function is called using a base class pointer, the function is looked up in the VTable
at runtime, ensuring dynamic binding.

(b) Rules for Virtual Functions

1. Declared in the Base Class with `virtual` keyword


2. Overridden in Derived Class (not mandatory, but recommended)
3. Always called based on the actual object type, not pointer type
4. Work only through pointers or references to the base class
5. Destructors should be virtual in a polymorphic class to ensure proper destruction of derived
class objects

5. Example With Virtual Destructor


🔴 Problem Without Virtual Destructor
cpp

#include <iostream>
using namespace std;

class Base {
public:
Base() { cout << "Base Constructor\n"; }
~Base() { cout << "Base Destructor\n"; } // Non-virtual destructor

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/13
};

class Derived : public Base {


public:
Derived() { cout << "Derived Constructor\n"; }
~Derived() { cout << "Derived Destructor\n"; }
};

int main() {
Base* ptr = new Derived();
delete ptr; // Memory leak - Derived class destructor not called
return 0;
}

Output:

nginx

Base Constructor
Derived Constructor
Base Destructor

❌ Derived class destructor is not called, causing a memory leak!


✅ Solution: Use Virtual Destructor
cpp

class Base {
public:
Base() { cout << "Base Constructor\n"; }
virtual ~Base() { cout << "Base Destructor\n"; } // Virtual destructor
};

class Derived : public Base {


public:
Derived() { cout << "Derived Constructor\n"; }
~Derived() { cout << "Derived Destructor\n"; }
};

int main() {
Base* ptr = new Derived();
delete ptr; // Proper cleanup
return 0;
}

Output:

nginx

Base Constructor
Derived Constructor
Derived Destructor
Base Destructor

✅ Both destructors are now correctly called!


6. Pure Virtual Function & Abstract Class
A pure virtual function is a function with no definition in the base class, making the class abstract.

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/13
cpp

class Base {
public:
virtual void show() = 0; // Pure virtual function (No definition)
};

class Derived : public Base {


public:
void show() override {
cout << "Derived class implementation" << endl;
}
};

int main() {
// Base obj; // ❌ ERROR: Cannot instantiate abstract class
Derived obj;
obj.show(); //
return 0;
✅ Works fine
}

✅ A class with at least one pure virtual function is called an abstract class, meaning it cannot be
instantiated directly.

7. Key Takeaways
Virtual functions enable dynamic binding and runtime polymorphism.
They allow function overriding to work correctly through base class pointers.
Always use a virtual destructor in polymorphic classes to prevent memory leaks.
Pure virtual functions make a class abstract, forcing derived classes to implement them.

Let me know if you need further clarification! 🚀

why do we use const key word in classes

Why Do We Use `const` Keyword in Classes in C++?

The `const` keyword in C++ is used inside classes to ensure that:

1. Certain member functions do not modify the object’s state.


2. Certain member variables remain immutable after initialization.
3. The integrity of constant objects is maintained.

1. `const` in Member Functions


Purpose:

A member function should be declared `const` when it does not modify any data members of the
class. This helps ensure read-only operations and enables calling the function on `const` objects.

Syntax:

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 9/13
cpp

return_type function_name() const;

Example:

cpp

#include <iostream>
using namespace std;

class Demo {
private:
int value;

public:
Demo(int v) : value(v) {}

void show() const { // Marking function as const


cout << "Value: " << value << endl;
}

void setValue(int v) { // Non-const function


value = v;
}
};

int main() {

✅ ❌
const Demo obj(10); // Creating a constant object
obj.show(); // Allowed (because `show()` is const)
// obj.setValue(20); ERROR (Cannot modify a const object)

return 0;
}

Output:

makefile

Value: 10

✅ Reason: `show()` is `const`, so it can be called on a `const` object.


🔴 If we remove `const` from `show()`, it will give an error:

pgsql

error: passing 'const Demo' as 'this' argument discards qualifiers

2. `const` in Member Variables


Purpose:

Ensures that the variable cannot be modified after initialization.


Must be initialized using initializer lists.

Example:

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 10/13
cpp

class Demo {
private:
const int value; // Constant member variable

public:
Demo(int v) : value(v) {} // Must be initialized in initializer list

void show() const {


cout << "Value: " << value << endl;
}
};

int main() {
Demo obj(100);

}
obj.show();
// obj.value = 200; ❌ ERROR (Cannot modify const member)

✅ Reason: `value` is `const`, so it must be initialized in the constructor and cannot be changed.

3. `const` in Function Parameters


Purpose:

Prevents modification of arguments passed to a function.


Useful for passing large objects by reference to avoid copying while ensuring they remain
unmodified.

Example:

cpp

void display(const string& str) { // `str` cannot be modified inside the function
cout << str << endl;
}

int main() {
string text = "Hello, World!";

}
display(text);
// text[0] = 'h'; // ✅
Allowed (text is non-const outside function)

✅ Reason: is passed by reference (`&`) to avoid unnecessary copying, but it cannot be modified
`str`
inside `display()`.

4. `const` in Pointers
Different Pointer Const Qualifiers:

cpp

const int* ptr1; // Pointer to const int (value cannot change)


int* const ptr2; // Const pointer to int (pointer cannot change)
const int* const ptr3; // Const pointer to const int (neither value nor pointer can change)

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 11/13
Example in Classes:

cpp

class Demo {
private:
int* const ptr; // Constant pointer

public:
Demo(int val) : ptr(new int(val)) {}

void show() const {


cout << "Value: " << *ptr << endl;
}

~Demo() { delete ptr; }


};

✅ Reason: `ptr` cannot be reassigned, ensuring memory safety.

5. `const` Objects
Purpose:

If an object is declared `const`, it can only call `const` member functions.

Example:

cpp

class Demo {
public:
void show() const { cout << "Const function" << endl; }
void modify() { cout << "Non-const function" << endl; }
};

int main() {

❌✅ERROR
const Demo obj;
obj.show(); // Allowed
// obj.modify(); (Cannot call non-const function)
}

✅ Reason: `const` objects can only call `const` functions to prevent modifications.

Key Takeaways
Feature Purpose Usage

`const` in member Prevents modifying the object inside the


`void show() const;`
functions function
`const` in member Ensures the value cannot be changed `const int x;` (must be initialized
variables after initialization in constructor)

`const` in function Prevents modification of passed `void func(const string&


parameters arguments str);`
Restricts modification of pointer or value
`const` in pointers `const int* p; int* const p;`
it points to

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 12/13
Feature Purpose Usage
Ensures only `const` functions can be
`const` objects `const ClassName obj;`
called

🔹 Use wherever possible to improve code safety and prevent unintended modifications!
🚀
`const`

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 13/13

You might also like