Start New Discussion within our Software Development Community

Is it possible to put a gap in a class definition? IE:

class a;
class b
a test;
a getA(){return test;}
class a
int i;
a(int i):i(i){}
a operator+(int o)const{return a(i+o);}
class b continued?//what? how?
void outputA(){cout<<a;}

This is just an example, I actually want this for a reason that will make code EASIER to read.

>>Is it possible to put a gap in a class definition?

No. But if you have a use-case we can surely tell you how to solve your problem. There is basically no need to be able to do this, because anything you want to do you can solve it better another way.

I seriously doubt that will make your code easier to read. With the definition being split up like that it actually makes it harder to read because you have to bounce around to find all the relevant parts of the class definition.

Ok, I have a class that holds an array of ints and a pointer to a special class that contains an array of glModels. This other class only allows access to the index of those models as ints, so I cannot overload the + or += operators to add things to those classes. So I made the () operator return an integer wrapper class with overloaded operators so that I can do statements like: MyClass(IndexOfMyModel)+=WhatIWantToAddToMyModel; This works fine, but the header file has the () operator a whole class definition away from the integer wrapper class' + operator, I want them to be right on top of each other.

Now it is:

class __glModelReferenceClass__;
class glWindow
    __glWindow__ *win;
    __glModelReferenceClass__& operator(int index){return __glModelReferenceClass__(win,index);}
    //more functions
class __glModelReferenceClass__
    __glWindow__ *win;
    int index;
    __glModelReferenceClass__(__glWindow__ *win):win(win){}
    __glModelReferenceClass__ &operator+=(glVertex vert){__AddVertA__(win,index);return *this;}
    __glModelReferenceClass__ &operator+=(float xyz[3]){__AddVertB__(win,index);return *this;}
    //more of these operators and the such

But where it says more functions it is many, many lines of code and comments describing each function to be exported to an index document. In this order the index of the () operator for glWindow is quite far from the += operators of __glModelReferenceClass__ so it is hard to read them. I have also left out some other things which are the reason for the __NAME__ or __NAMEVERSION__ of some of the classes and functions.

Before I say anything else, I must point out a few disturbing things.

First, this line:

__glModelReferenceClass__& operator(int index){return __glModelReferenceClass__(win,index);}

Should have been flagged with a compilation warning (if not, increase the warning level to the maximum, as you always should). This function returns a non-const reference to a temporary object. You shouldn't do this, it has undefined behavior, and even if it works, it doesn't mean it's OK to do it. Moreover, there is no need for a reference here, just return it by value (generally proxy-classes should be passed around by value because they are semantically just wrappers for a pointer, a reference, an index-container pair, etc.). Just do this:

__glModelReferenceClass__ operator(int index){return __glModelReferenceClass__(win,index);}

Second, you use the double underscore naming convention quite a lot. I don't know where you picked that up, it is not only illegal (at least for global identifiers as you have there) because names with leading underscores are reserved for the compiler-vendors, but it is also horrible readability-wise. If you want to distinguish your class names from other class names (like glWindow, not interfering other possible glWindow names) then use a namespace, that's what they're for, and you should use a namespace to encompass your code.

Third, when it comes to operator overloading, you should not overload operators in a way that breaks the semantics of the operator. An addition operator is supposed to perform an addition, not an insersion or concatenation or whatever your += operators are doing. In C++, the idiomatic operators that can be used to do such things (if you even should be using operator overloading in this case) are the << and >> operators (in the same way a iostreams), and the also have the nice property of being left-associative which allows you to make those nice looking chains like with iostream. I highly recommend that you use that operator instead, and that you make them friend functions instead of member functions. Also note that the += operator (and similar operators) are right-associative which will make the chaining of additions of vertices very weird (either in reverse order, or with an abominable number of parentheses).

Now, to solve your problem, In most cases, for this type of proxy classes, you can just make it a nested class. I can't really tell if you need the proxy class to be nested in "glWindow" or in "__glWindow__", that's for you to see. Also note that in your code, you don't really need to forward-declaration because the "__glModelReferenceClass__" class doesn't need to know about the "glWindow" class, only that other "__glWindow__" class. Frankly, I think that the whole design seems very awkward.

I assume that your __glWindow__ class contains a bunch of models, and that each model contains a bunch of vertices (with normals, texcoords, etc.). My understanding is that your glWindow class, given an index, returns a proxy to the model in question, which can then be manipulated via the proxy (to add vertices and so on). I would say, skip the middle-man, i.e., the proxy. The alternative I would suggest is simply that the glWindow class returns a reference to the model at the given index, and the model class itself should have to necessary functionality to be manipulated directly. That would be a lot easier and clearer to the user, and simpler to program, and more flexible. This simpler architecture makes it clear that a glWindow contains a bunch of models and that models can be manipulated in a number of ways. The way you have it tied up now is very circumvented for what it does.

N.B. If you have trouble with the fact that definitions of related classes are very far apart, making the reading of the code difficult (because you have to scroll back and forth into different sections of the code to understand the whole thing) then it probably means that you have classes that are too monolithic (huge classes that do a lot of things instead of small classes with clear responsibilities), and that is a design flaw in general. If it has to be that way, then use documentation to your advantage, learn to use doxygen and generate useful documentation with it.

Ok, first of all the __NAME__ thing is not actually that, it is DLL_FUNCTION__NAME (It is for my documentation reader to not show them) Also, what is Doxygen?

>>Also, what is Doxygen?

What is doxygen? A documentation generation system that is used extensively in most prevalent programming languages. It is quite awesome actually. Basically, the process is that you put comment blocks in front of each element you wish to document and doxygen will pick them up and generate documentation from them (either as html, latex, rtf, chm, qch, etc.) with full cross-referencing and block-diagrams (inheritance graphs, dependency graphs, call-graphs, etc.).

Here is an example of how it looks in the code:

/// \brief Computes the square.
 * This function will compute the square of a number. 
 * \param X The operand of the square operator.
 * \return The square of X.
 * \author Mikael Persson <mike_2000_17@daniweb>
 * \date Oct. 14, 2011
double sqr(double X);

When all the interesting parts of your code has documentation in the style of the above (and there are more tags too) you can use the doxygen program, configure it the way you want the output to be, the input source-code folders and filters (for files or source code elements), and then you hit "generate" and you have awesome detailed documentation for your code.

Read more about it here. Doxygen is really something that no C++ programmer should ignore. It's a standard tool that everyone uses for generating code documentation. Here are some examples of the output.

WOW! That is perfect!!! I was trying to do all this order and weird comment stuff because I was using a very weak, self-made documentation program. This Doxygen thing renders my problem mute. Thank you!

This question has already been answered. Start a new discussion instead.