Safety Tips
I am compiling a list of practices that people can use to increase the security, reliability, and stability of their code.
http://lspiroengine.com/?p=202
I wrote that after having some drinks (notice how being stumbling drunk does not affect my typing, wow!) so I couldn’t remember all of my ideas at the time so I have a few more to add soon, but at the same time I am open to more suggestions from the community.
What kinds of things do you do to keep your code safe and leak-free?
L. Spiro
http://lspiroengine.com/?p=202
I wrote that after having some drinks (notice how being stumbling drunk does not affect my typing, wow!) so I couldn’t remember all of my ideas at the time so I have a few more to add soon, but at the same time I am open to more suggestions from the community.
What kinds of things do you do to keep your code safe and leak-free?
L. Spiro
No discussion of safety and C++ is complete without liberally hammering home the point of RAII :-)
Good start, though; I'm sure there's more that could be thought of but nothing immediately rushes into my head (well, aside from RAII). Exception safety might be worth delving into a bit, for instance, or maybe some API-specific stuff on how not to do terribly bad things, but that starts to wander into the land of specificity and makes it somewhat less generally applicable.
Good start, though; I'm sure there's more that could be thought of but nothing immediately rushes into my head (well, aside from RAII). Exception safety might be worth delving into a bit, for instance, or maybe some API-specific stuff on how not to do terribly bad things, but that starts to wander into the land of specificity and makes it somewhat less generally applicable.
I got few suggestions for you [color=#3F454B][font=monospace]CBase [/font]class. Disable copy constructor and assignment operator to it. Use only private data members (or use a struct.) It's better to just delete in the destructor instead of calling virtual functions. I'd avoid inheriting implementation.
Suggestions:
1, Can you make the font bigger? It's too small for me. Though I can increase the font size, it's better if the default one is big enough.
2, Can you bold each important point of each buillet points so the readers can grasp the sole without reading the whole article?
1, Can you make the font bigger? It's too small for me. Though I can increase the font size, it's better if the default one is big enough.
2, Can you bold each important point of each buillet points so the readers can grasp the sole without reading the whole article?
Although you have a valid point there, I think the wording "virtual functions are not virtual inside constructors and destructors" could be improved, it is somewhat misleading (or even wrong).
The code snippet you posted does not work because it assumes that the base's destructor will call the derived class' virtual function to clean up. This is a well-known pitfall, but the issue is not that virtual functions are not virtual functions, but that the type of object during a constructor or destructor is, well, the actual type with the constructor's name, not some derived class as one might expect (and therefore one should avoid that kind of stuff if possible, just to be sure).
But regardless, virtual functions work perfectly well inside constructors and destructors (though statically resolved, because the compiler knows the exact type at that time), they are just dangerous because a seemingly harmless line of code does not necessarily do what one thinks. But they certainly behave like they should.
If you have e.g.
then A::A will call A::v, B::B will call B::v, and C::C will call C::v, because the type is A inside A::A, and B inside B::B, and so on. It works the same way in destructors.
Assuming that e.g. B::B will call A::v or A::A will call C::v or A::~A will call C::v is just not how C++ works. But regardless, a virtual function that you overload in B behaves like the B version of the function just as it should. It's not like it is just "gone" or replaced with the base class or something else (which is kind of how "virtual functions are not virtual" sounds like).
The code snippet you posted does not work because it assumes that the base's destructor will call the derived class' virtual function to clean up. This is a well-known pitfall, but the issue is not that virtual functions are not virtual functions, but that the type of object during a constructor or destructor is, well, the actual type with the constructor's name, not some derived class as one might expect (and therefore one should avoid that kind of stuff if possible, just to be sure).
But regardless, virtual functions work perfectly well inside constructors and destructors (though statically resolved, because the compiler knows the exact type at that time), they are just dangerous because a seemingly harmless line of code does not necessarily do what one thinks. But they certainly behave like they should.
If you have e.g.
struct A { A() { v(); }; virtual void v(){}; };
struct B : public A { B() { v(); }; virtual void v(){}; };
struct C : public B { C() { v(); }; virtual void v(){}; };
then A::A will call A::v, B::B will call B::v, and C::C will call C::v, because the type is A inside A::A, and B inside B::B, and so on. It works the same way in destructors.
Assuming that e.g. B::B will call A::v or A::A will call C::v or A::~A will call C::v is just not how C++ works. But regardless, a virtual function that you overload in B behaves like the B version of the function just as it should. It's not like it is just "gone" or replaced with the base class or something else (which is kind of how "virtual functions are not virtual" sounds like).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement