← Back to C++ Course | Chapter 9: Inheritance | Lesson 8 of 8

C++ की Virtual Base Class

एक virtual base class यह पक्का करता है कि एक shared grandparent एक diamond-shaped family में सिर्फ एक बार शामिल हो, एक set of grandparents share करने वाले दो siblings की तरह। यह duplicate copies solve करता है।
Syntax
cpp
class Base { };

class Left : virtual public Base { };
class Right : virtual public Base { };
class Derived : public Left, public Right { };

Virtual Base Classes क्यों?

जब एक diamond-shaped inheritance pattern exist करता है, एक naive derived class shared grandparent class की दो अलग copies के साथ खत्म होती है — हर parent के जरिए एक।

उस grandparent को एक virtual base class मार्क करना यह पक्का करता है कि हमेशा सिर्फ एक, shared copy बने, चाहे इस तक कितने भी paths जाएं।

उदाहरण: Why Virtual Base Classes?

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

// Define the type Grandparent
class Grandparent {
// Members below can be accessed from outside the class
public:
	int value = 1;
};

// Define the type ParentA
class ParentA : virtual public Grandparent {};
class ParentB : virtual public Grandparent {};
class Grandchild : public ParentA, public ParentB {};

// Program execution starts in main()
int main() {
	Grandchild g;
	// Print to the console with cout
	std::cout << g.value << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Virtual Base Classes Declare करना

आप intermediate classes में inheritance declaration के दौरान virtual keyword add करके एक virtual base class declare करते हैं; जिस order में आप virtual और public जैसा access specifier लिखते हैं वह compiler के लिए मायने नहीं रखता।

उदाहरण: Declaring Virtual Base Classes

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

// Define the type Base
class Base {
// Members below can be accessed from outside the class
public:
	int value = 10;
};

// Define the type DerivedA
class DerivedA : virtual public Base {};
class DerivedB : virtual public Base {};

// Program execution starts in main()
int main() {
	DerivedA a;
	// Print to the console with cout
	std::cout << a.value << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Virtual Base के साथ Constructor Rules

एक virtual base class के साथ, shared grandparent का constructor call करने की responsibility पूरी तरह नीचे most-derived (grandchild) class पर shift हो जाती है — C++ जानबूझकर intermediate parent classes की उस constructor को खुद call करने की किसी भी कोशिश को ignore करता है।

उदाहरण: Constructor Rules with Virtual Base

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

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

// Define the type ParentA
class ParentA : virtual public Base {};
class ParentB : virtual public Base {};

class Grandchild : public ParentA, public ParentB {
// Members below can be accessed from outside the class
public:
	Grandchild() : Base() { std::cout << "Grandchild constructed" << std::endl; }
};

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

Grandparent Members Access करना

क्योंकि virtual base class का सिर्फ एक instance exist करता है चाहे इस तक कितने भी derivation paths जाएं, किसी भी subclass से इसके member variables modify करना उस single shared copy को बदलता है, hierarchy में हर path से consistently visible।

उदाहरण: Accessing Grandparent Members

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

// Define the type Base
class Base {
// Members below can be accessed from outside the class
public:
	int shared = 0;
};

// Define the type ParentA
class ParentA : virtual public Base {};
class ParentB : virtual public Base {};
class Grandchild : public ParentA, public ParentB {};

// Program execution starts in main()
int main() {
	Grandchild g;
	g.shared = 99;
	// Print to the console with cout
	std::cout << g.shared << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Destructor Sequence

Virtual inheritance में, single shared virtual base object सबसे आखिर में destroy होता है, हर path पर हर subclass के अपना destructor चला चुकने के बाद — special-cased construction order का उल्टा।

उदाहरण: Destructor Sequence

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

// Define the type Base
class Base {
// Members below can be accessed from outside the class
public:
	~Base() { std::cout << "Base destroyed last" << std::endl; }
};

// Define the type ParentA
class ParentA : virtual public Base {
// Members below can be accessed from outside the class
public:
	~ParentA() { std::cout << "ParentA destroyed" << std::endl; }
};

class Grandchild : public ParentA {
public:
	~Grandchild() { std::cout << "Grandchild destroyed first" << std::endl; }
};

// Program execution starts in main()
int main() {
	Grandchild g;
	// 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. inheritance पर virtual keyword भूल जाना।
  2. यह भूल जाना कि most derived class को virtual base constructor call करना ज़रूरी है।
  3. virtual inheritance इस्तेमाल न करने पर ambiguity।
चैप्टर सारांश
  • Inheritance एक class को दूसरी reuse और extend करने देता है, access control यह affect करते हुए कि derived classes क्या देख सकती हैं।
  • Single, multiple, multilevel, hierarchical, और hybrid inheritance अलग class relationships describe करते हैं।
  • एक virtual base class multiple inheritance में duplication avoid करने में मदद करता है।

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.