C++ की Virtual Base Class
In this page:
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?
// 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;
}
Login to try C/C++/Java/PHP code in the editor
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
// 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;
}
Login to try C/C++/Java/PHP code in the editor
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
// 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;
}
Login to try C/C++/Java/PHP code in the editor
Grandparent Members Access करना
क्योंकि virtual base class का सिर्फ एक instance exist करता है चाहे इस तक कितने भी derivation paths जाएं, किसी भी subclass से इसके member variables modify करना उस single shared copy को बदलता है, hierarchy में हर path से consistently visible।
उदाहरण: Accessing Grandparent Members
// 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;
}
Login to try C/C++/Java/PHP code in the editor
Destructor Sequence
Virtual inheritance में, single shared virtual base object सबसे आखिर में destroy होता है, हर path पर हर subclass के अपना destructor चला चुकने के बाद — special-cased construction order का उल्टा।
उदाहरण: Destructor Sequence
// 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;
}
Login to try C/C++/Java/PHP code in the editor
- inheritance पर
virtualkeyword भूल जाना। - यह भूल जाना कि most derived class को virtual base constructor call करना ज़रूरी है।
- 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 करने में मदद करता है।
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: