Using C++ Aug 19, 2006
I started programming in Basica when I was very young, but after a few years my programs got more complicated and I started running into limits inherent in the language. I gradually switched to C over the next few years. At some point I started using Turbo C++, and have been using C++ ever since, albeit with occasional compiler upgrades (Turbo->Watcom->MSVC 6.0->MSVC 2005.) I did however write mostly C-style code until as little as 4 years ago.
I now do things like declaring my data private, and trying to have a well-defined interface of public functions to a class. I'll never believe that literally hiding implementation is a good thing( sometimes code can tell you if a function is effecient, cover holes in documentation, and help with debugging. ) However I've always valued ease of changing implmentation and using a class. I guess I'm a reluctant convert to object-oriented programming. Although I only do things because I've found them to be practical and I never ask myself if anything is "proper" or "true" Object Oriented programming. How I use C++
Usually my class structure is just a two level tree, and the first level of the tree has some( or all ) pure virtual functions, and so only derived classes can be created. For example, I have an object base class, then many different types of object classes. Also, I have an Asset Base for Asset Types, and an Editor Base Class for World Editor & Asset Editors. The base classes serve as interfaces, and include any common functionality. I also have a lot of class types without any inheritance defined. For example there are primitive classes like Vector, Matrix, and Quaternion, which make extensive use of overloaded operators. I also use some slightly less primitive classes such as Bounding Box, Frustum, and Camera. I use a templated keyframe manager class for different types of keyframes (object key, joint key, morph key, properties key.) I suppose I could, and maybe should, have made a base keyframe class with virtual functions. My reasoning for using only templates was to keep keyframes fast and lean. For different Asset Managers( meshes, skeletons, animations, materials, etc. ) I use a templated asset manager class that is derived from a non-templated base class. Therefor each asset manager stores one type of asset, but the base class is there to provide a common interface. A Few Tips
These tips are mainly some useful things I learned about C++ over the years. They're not meant to be obscure so you might already know them all.
const is used to tell the compiler that a variable won't change. But what about const at the end of a function defintion like in the example below? It means that the function won't change the member variables. inline CVec3 operator+ (const CVec3& V2) const { return CVec3( x + V2.x, y + V2.y, z + V2.z); } If you want to create a const member variable in a class, you set its value in a .cpp file like this: // In header static const CVec3 ZERO; // In cpp file const CVec3 CVec3::ZERO( 0, 0, 0 ); The compiler treats enums as their own type, although internally they are exactly like an integer. This means you can create a function that takes an enum, like enum eRender_t { REND_SOLID, REND_ALPHA, REND_BOTH }; void Render( eRender_t RenderMode );then you can look at the enum to see the named values the function can take, and the compiler will complain if you send the function an improper value. A derived class will always call the base class' constructor or destructor. The actual order on ctors is base then derived, and on dtors derived then base. Destructors can be declared virtual, but as stated above (unlike a normal function) they will automatically call the base dtor. I have a virtual dtor for my object class, because my world class contains a std::vector< ObjectBase* > pObjectList; that is filled with pointers to all types of objects. With a virtual dtor, I can call delete pObjectList[ DelIndex ]; You can call an overloaded virtual function in your base class( eg. ObjectBase ) from within one of its derived classes like this
TerrainObject::FunctionName()
{
// do terrain stuff here
ObjectBase::FunctionName();
}
If you have a class with member variables that are pointers you need to define your own assignment operator( and copy constructor ). If you don't think it needs to be copied, you can safeguard by defining a function without an implementation like this: private: MyClass& operator=( const MyClass &In ); MyClass( const MyClass &In );Now the compiler will complain if either of these are called. Even if you don't use = on it yourself, some things like an std::vector may use these functions on contained objects. External Link
C++ FAQ Lite: A good page to learn about C++.
|