See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  C++ Components And Sub-Components
  Submitted by



It is highly important to have your code components, whether they're coded in C or in C++, to be divided into sub-components, so that if you'd like to modify something small in your code you would just change it in the sub-component instead of going through your whole source code and changing those bits, which also may cause bugs and errors. You better keep your code as generic as possible in order to be able to enjoy code reusability which means using methods to acess the members of your class. Learning about design patterns would help a great deal.

In order to show you how important it is to keep your code abstract I'll demonstrate it with a simple example. Let's say that you are about to work with triangles only. A basic triangle class would usually have three indices(each one points to it's vertex number in vertex_list).

class triangle {
	public:
		int a, b, c; // the indices

		triangle() {}

triangle(int A, int B, int C) { // constructor set(A, B, C); }

void set(int A, int B, int C) { // functions to set the indices a=A; b=B; c=C; }



};


Simple enough? If you want to access the first vertex forming this triangle you'd just do, assuming my_triangle is variable of triangle class, v1 = vertex_list[my_triangle.a];



Now you probably got a cool model loading working very nicely and you're damn pleased with yourself. Imagine yourself after sometime finding out that rendering n-gons can be quite fast and many popular games render n-gons instead of your simple triangles. You'd find yourself in a dilemma if you're using a class like the first triangle class.





Here is how you could design your triangle class to be more general:

#define MAX_VERTICES_IN_POLY 3
class triangle {
		int indices[MAX_VERTICES_IN_POLY];
	public:
		triangle() {}

int& set(int num) { // an accessor method return (int)get(num); // uses a sub-component to get a reference to an index of a vertex }

const int& get(int num) { // don't forget to include assert.h assert(num=0 && num<MAX_VERTICES_IN_POLY); return indices[num]; } };


We have changed the a,b,c to indices[3], there are already three good things with this approach:

  • 1).OpenGL and Direct3D API's use an array of indices to draw a polygon.
  • 2).If you want to change it to quads you would just need to change from 3 to 4 in the MAX_VERTICES_IN_POLY definition.
  • 3).If you desire to have n-gons, all you'd need to do is just to make the indices a pointer (int *indices) , add another member (int nverts) and last but not least to change from num<MAX_VERTICES_IN_POLY to num<nverts.


  • See how easy it is to create a generic code. If you want to get the fifth vertex of the n-gon you'd just do: v5 = vertex_list[my_triangle.get(5)];



    To set a new index you'd do my_triangle.set(4) = 7; or whatsoever..



    Our final class:

    class polygon {
    	int *indices;
    	int nverts;
    public:
    // constructor
    	polygon() { indices=NULL; nverts=0; }

    int& set(int num) { // an accessor method return (int)get(num); // uses a sub-component to get a reference to an index of a vertex }

    const int& get(int num) { assert(num=0 && num<nverts); return indices[num]; }

    // allocates memory for a new polygon void create(int num_of_verts) { indices = new int[num_of_verts]; nverts = num_of_verts; }

    // frees the memory of our polygon void destroy() { if (indices) delete []indices;

    nverts=0; }

    // destructor ~polygon() { destroy() }; }


    The idea is clear, some would use indices, some would store the vertices directly in triangle class, some use linked lists for storing vertices in their polygon class.The point is that using such an abstract class you could change from one to other without any problems. Try now to imagine all the pain you'd be going through if you had used the first triangle class.



    Useful resources:
  • www.hugi.de or www.foxfiber.net/hugi - tutorial about design patterns can be find in issue 18 and tips and tricks about c++ in issue 19.

  • http://www.bruceeckel.com/ - I heard that thinking in C++ by Bruce Eckel is quite good, haven't read it though.

  • Design Patterns : Elements of Reusable Object-Oriented Software
    Authors: Gamma, Helm, Johnson, and Vlissides
    Publisher: Addison-Wesley
    ISBN: 0201633612 Not so long ago started reading this book and it's fantastic.

  • The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

     

    Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
    Please read our Terms, Conditions, and Privacy information.