views:

163

answers:

5

I have a class that contains some data: class DATA

Now I would to create some functions that uses those data. I can do it easily by writing member functions like DATA::usedata();

Since there are hundreds of functions, I would to keep an order in my code, so I would like to have some "categories" (not sure of the correct name) like:

DATA data;
data.memory.free();
data.memory.allocate();
data.file.import();
data.whatever.foo();

where memory, file and whatever are the "categories" and free, allocate and foo are the functions.

I tried the inheritance way, but I got lost since I can not declare inside DATA a memory or file object, error C2079 occurs: http://msdn.microsoft.com/en-us/library/9ekhdcxs%28VS.80%29.aspx

Since I am not a programmer please don't be too complicated and if you have an easier way I am all ears.

+2  A: 

The easiest way would be to do the categories just as a naming convention. If you replace the . with _ you don't need any "subobjects" and get:

data.memory_free();
data.memory_allocate();

data.file_import();

This way you basically have the same function names but avoid all the implementation problems of the subobject approach.

sth
When you have hundreds of function in a single class and the information can be divided into specialized classes one should do so. Otherwise, it would be like writing thousands of lines of code in int main() {} when you can break the information in many smaller functions. It will be less of a mess to understand the code and it will force the person to write cleaner code. One should use the full potential of OOP and not just have a brick of information in one single class.
Alerty
@Alerty: I don't think this gets much better if you only divide the functions into different "namespaces" that all work on the basic `data` object. To suggest how `Data` could be split up in a more OO design there really isn't enough information.
sth
A: 

If you have a class that has hundreds of member functions, you almost certainly need to break that up into multiple classes. To achieve the type of naming syntax that you're after you could use name spaces to group related classes into "categories."

bshields
A: 
class DATA
{
public:
    class CategoryA_Class
    {
        friend DATA;

    private:
        CategoryA_Class() { }

    public:
        bool GiveMeSomeInt() { return 1; }
    };

    class CategoryB_Class
    {
        friend DATA;

    private:
        CategoryB_Class() { }

    public:
        bool GiveMeSomeBool() { return true; }
    };

public:
    CategoryA_Class CategoryA;
    CategoryB_Class CategoryB;
};

int _tmain(int argc, _TCHAR* argv[])
{
    DATA mydata;

    int a = mydata.CategoryA.GiveMeSomeInt();
    bool b = mydata.CategoryB.GiveMeSomeBool();

    return 0;
}
Diego Pereyra
+4  A: 

Give your data class some classes of its own, and let those classes refer to the data object that holds them. It sounds like you might have tried to do that already. If you got an error, then you were doing something else wrong.

struct DATA
{
  struct DataMemory
  {
    DATA& data;
    DataMemory(DATA& d): data(d) { }
    void free();
    void allocate();
  };
  struct DataFile
  {
    DATA& data;
    DataFile(DATA& d): data(d) { }
    void import();
  };
  struct DataWhatever
  {
    DATA& data;
    DataWhatever(DATA& d): data(d) { }
    void foo();
  };

  DataMemory memory;
  DataFile file;
  DataWhatever whatever;
  DATA(): memory(*this), file(*this), whatever(*this) { }
};

Each of the inner classes has a member that's a reference to the containing DATA object. They have constructors to allow that member to get assigned. The DATA class itself also has a constructor to initialize each of its members with a reference to itself.

You can now implement the functions and refer to any of the DATA object's members.

void DATA::DataMemory::free()
{
  data.whatever.foo();
}

The inner classes aren't required to be inner classes; they could be standalone top-level classes like DATA if you want, but I think nesting them helps show their interdependence.

Rob Kennedy
Interesting. Me like it even if I don't have an immediate use for that "pattern".
Max
A: 

It is normal to feel confuse when you have so many functions in one class. The trick is to break it all up so that the information is contained in smaller classes that inherits a parent class that has common functions and data to all children.

From what I see you already found a common name for the information. class DATA can be that parent class. Now, you need to break up the information into types of Data. In other words, you will have children classes that will be specialized in something. A quick way to divide the information is to create a diagram of a parent class linked with children classes.

Here is a small example of what you could do:

//parent class
template <class T> class Data
{
   T data_; //you could use an array like a std::vector or 
            //use a stream

public:
//...
   void foo();
   T getData() const;
};

//child class
template <class T> class Memory 
    : public Data
{
public:
   void free();
   void allocate(T data);
//...
}; 

//child class
template <class T> class File 
    : public Data
{
public:
   T readFile(); //could read the contents of a 
                 //file and save it in data_ (class member from parent class)

   void writeFile(); //could write data_ 
                     //(class member from parent class) to a file
//...
}; 

Also, here is documentation if you need help on the concept of inheritance.

Alerty