← Back to C++ Course | Chapter 10: Polymorphism & Abstraction | Lesson 10 of 11

C++ में Object Slicing

Object slicing तब होता है जब एक child object को एक parent variable में copy किया जाता है और इसके extra parts काट दिए जाते हैं, एक sandwich slice करने और top layer खोने जैसा। Pointers या references इस्तेमाल करना इसे avoid करता है।
Syntax
cpp
class Base { /* members */ };
class Derived : public Base { /* extra members */ };

Derived d;
Base b = d;   // slicing: only the Base part is copied

Object Slicing क्या है?

Object slicing तब होता है जब एक derived-class object को एक plain base-class object को value से assign किया जाता है: क्योंकि base object में सिर्फ base class के members के लिए जगह होती है, derived class का सारा extra data assignment में 'slice off' होकर खो जाता है।

उदाहरण: What is Object Slicing?

cpp
// Include std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	int legs = 4;
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	std::string breed = "Labrador";
};

// Program execution starts in main()
int main() {
	Dog d;
	Animal a = d;
	// Print to the console with cout
	std::cout << a.legs << std::endl;
	return 0;
}

Value Assignment पर Slicing

जब आप एक derived object को सीधे एक already-declared base-class variable में assign करते हैं, base class का copy-assignment operator चलता है, और इसे derived class के extra members का बस कोई ज्ञान नहीं होता — या उनके लिए जगह नहीं होती — इसलिए वे पूरी तरह discard हो जाते हैं।

उदाहरण: Slicing on Value Assignment

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

// Program execution starts in main()
int main() {
	Dog d;
	Animal a = d;
	a.speak();
	// Return 0 to signal that the program finished successfully
	return 0;
}

Pass-by-Value पर Slicing

एक derived object को एक ऐसे function में pass करना जो अपना parameter value से (एक plain base-class type की तरह) accept करता है उस call के अंदर base class का copy constructor trigger करता है, जो function body के actually चलना शुरू करने से पहले ही object को सिर्फ इसके base हिस्से तक slice कर देता है।

उदाहरण: Slicing on Pass-by-Value

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal a) {
	a.speak();
}

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(d);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Pointers से Slicing रोकना

Slicing रोकने और एक object का पूरा polymorphic behavior preserve करने के लिए, हमेशा base class values की बजाय base class pointers इस्तेमाल करके derived objects pass और store करें — एक pointer बस एक address hold करता है, इसलिए slice करने के लिए कुछ नहीं है।

उदाहरण: Preventing Slicing with Pointers

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal *a) {
	a->speak();
}

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(&d);
	// Return 0 to signal that the program finished successfully
	return 0;
}

References से Slicing रोकना

आप pointers की बजाय base class references इस्तेमाल करके same protection achieve कर सकते हैं: एक derived object को एक base class reference type के function parameter को pass करना बिल्कुल भी कोई copy trigger करने से बचता है, इसलिए object के derived members intact रहते हैं।

उदाहरण: Preventing Slicing with References

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Animal
class Animal {
// Members below can be accessed from outside the class
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

// Define the type Dog
class Dog : public Animal {
// Members below can be accessed from outside the class
public:
	void speak() override { std::cout << "Dog" << std::endl; }
};

void makeSpeak(Animal &a) {
	a.speak();
}

// Program execution starts in main()
int main() {
	Dog d;
	makeSpeak(d);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक derived object को एक base variable में value से assign करना, जो derived members slice कर देता है।
  2. एक base parameter लेने वाले एक function को value से एक derived object pass करना।
  3. एक vector<Base> में derived objects store करना, जो सिर्फ base हिस्सा copy करता है; इसकी बजाय pointers store करें।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.