0

I created a custom library that is usually used as a parent class.
After I used it for 1 month, I begin to face difficulty about its readability.

It is better described by a simplified real example.

Library Level

There is my c++ library to manage Object in 2D space.

It has 2 classes : Grid (the space) and GridMember (object in space).

Game-logic Level

I create a Table derived from Grid, and Ball derived from GridMember.

Problem

When I want to call function of Grid from Table like this:-

Table* table=new Table();
table-> .... some Grid's function .... (ctrl-space)

If ALL Grid's function name have some unique signatures e.g. all of them has prefix grid_,
... the code will gain higher readability.

As you can see, it is captivating:-

table->grid_add(new Ball());               //Grid's function member
table->grid_moveTo(ball1,VecInteger(3,4)); //Grid's function member
table->flip();                             //not Grid's function member

However, when look inside Grid.h, now it is very dirty.
Every variable/function of Grid now contains that grid_.

This is one of the worst symptom :-

class Grid{
    //--------- old version -------
    void move_grid_to_offset(){...} //move the world
    //^ I prefer this name to moveGridToOffset, because it is easier to read

    //--------- new version ---------
    void grid_move_grid_to_offset(){...} 
    //^ After a long day, I read it as  grid......grid(again)..  
    //         not sure what it is doing
}

Therefore readability is reduced.

Question

How to achieve high readability in both places?

Similar question : Why use prefixes on member variables in C++ classes but it is not related to this problem.

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67
  • 1
    `Table* table=new Table();` written like a true java lover :) C++ doesn't require you to `new` everything. In fact, in most cases you shouldn't and just hurt the maintainability and efficiency of your code. – StoryTeller - Unslander Monica Jun 19 '16 at 14:45
  • :D, it is my bad habit, I know I can Table table; – javaLover Jun 19 '16 at 14:47
  • If you don't mind repeating yourself, you can add a bunch of inline short wrappers. The non member `grid_move_to_offset(Grid&, /*params*/)` will do c++11 perfect forwarding to `Grid::move_to_offset` – StoryTeller - Unslander Monica Jun 19 '16 at 14:47
  • You really should become re-accustomed to value semantics and auto storage when writing c++. It makes life so much easier in the long run. – StoryTeller - Unslander Monica Jun 19 '16 at 14:49
  • Yes, I accept that I am careless. Now for you solution. I am interested, if you don't mind, please provide more detail. I have looked into namespace, but it can't be used inside class. – javaLover Jun 19 '16 at 14:50
  • 1
    The solution I have in mind is something akin to `inline void grid_func1(const Grid& grid) { grid.func1(); }`. Not really pleasant, but gives you flexibility. Another thing you should reconsider, is if a `Table` **really is** a `Grid`. Because IMHO, it shouldn't matter where the member function originates. Any decent code explorer will take you the right place anyway. – StoryTeller - Unslander Monica Jun 19 '16 at 14:54
  • 2
    Just drop all the prefixes. Not needed in the slightest. If you find `table->move` less intuitive than either `grid->move` or `table->grid_move`, you probably should have not used inheritance in this case. Evaluate containment instead. As the last resort, write `Grid* Table::grid() { return this; }` and use `table->grid()->move`. – n. m. could be an AI Jun 19 '16 at 15:04

1 Answers1

1

In general, any member of a subclass should actually be a member of any superclass, conceptually as well as programatically. Thus, in this case, any Table actually is a Grid, and any Ball actually is a GridMember. Since a Table is a Grid, Table->add() should be perfectly clear, without worrying about whether it's a Grid function or a Table function.

In the case of move_grid_to_offset, the issue is not that there's too little information in the name, but that there's already too much: a better name would be move_to_offset or offset_by. Since you already know that it's a grid whose member function is being invoked, it's unnecessary to repeat in the name of the member function that it applies to the grid: grid.offset_by() is perfectly clear. And table.offset_by() is also perfectly clear, even if we don't know about the Grid class at all.

Warren Dew
  • 8,790
  • 3
  • 30
  • 44