Making C++ Classes inherit from C Structs, Recommended?
I was recently doing some Windows Api coding (still doing it). And I was trying to find the best way to wrap the WNDCLASSEX into a C++ class, when I had this crazy idea, the WNDCLASSEX is a struct right? (even though it is written in c) and in C++ structs are treated as classes, so why d开发者_运维技巧on't I declare my WinCLass as a derivative of WNDCLASSEX , so I tried:
class WinClass : protected WNDCLASSEX
And it worked! Then I tried using it with SDL structs but those worked too. But some structs(especially SDL ones) either don't compile or cause unexplained runtime errors when I derive classes from them. So my question: Is this kind of C struct use recommended? Is it actually used by pros, or is it just a lame hack? Should I use for my wrapppers or apps, or will this just introduce unexplained bugs?
As long as you don't start adding virtual members, it should be fine. If you do add virtual members, the virtual table pointer could screw with your memory layout of the struct.
This includes virtual destructors!
The only difference between a class and a structure in C++ is that of Access specifiers.
For classes the access specifier is private by default.
For structures the access specifier is public by default.
This means if you have a class deriving from other class/struct it will be private inheritance by default &
If you have a structure deriving from other class/structure it will be a public inheritance by default.
One problem though is that since for structure default access specifier is public, they may expose members that maybe should not be exposed to deriving classes. The entire encapsulation has a whole new dimension in this sense. Ofcourse, You If you can change the access specifiers inside the structure which you intend to use as Base, then it is possible to avoid the problem, but it may not be possible because that might affect how the structure is being used from other parts of the program.
EDIT:
Through the comments, I have a fair idea now, what errors you are referring to, the errors are not specifically because you are deriving from a structure but because you are misunderstanding the rules of Inheritance & Access specifiers.
Here is a sample program for demonstration:
#include<iostream>
using namespace std;
struct FirstStruct
{
private:
int a;
public:
int b;
FirstStruct():a(10),b(20),c(30)
{
}
protected:
int c;
};
class MyClass:protected FirstStruct
{
public:
int i;
MyClass():i(40),j(50),k(60)
{
}
void doSomething()
{
a = 100; //private in Base is not accessible in Derived
b = 100; //Accessible
c = 100; //Accessible
i = 100; //Accessible
b = 100; //Accessible
c = 100; //Accessible
}
private:
int j;
protected:
int k;
};
int main()
{
MyClass obj;
obj.i = 100; //Accessible
obj.j = 100; //Error Cannot be Accessed, j is private member
obj.k = 100; //Error Cannot be Accessed, k is protected member
obj.a = 100; //Error Cannot be Accessed, a is private member in Base Class
obj.b = 100; //Error Cannot be Accessed;
//b is protected member of MyClass, because of protected Inheritance
obj.c = 100; //Error Cannot be Accessed;
//same reason as b
obj.doSomething();
return 0;
}
You can check running the same here at Ideone.
You will notice even If you change the type of the Base from struct FirstStruct
to class FirstStruct
here you get the same errors(nothing more nothing less).
Suggest you to have a look at this answer here, to clear your understanding on Inheritance and Access specifier rules.
I don't have much experience with the Win API, but I know that in C++ the only difference between classes and structs is the default visibility. For classes it is private and for structs it is public. In other words, it is OK to a class be a subclass of a struct.
Keep in mind that as it is a good pratice to declare a virtual destructor for any base class, the struct you are subclassing won't have it.
精彩评论