Wednesday, August 30, 2017

May the CONST be with you

In C++, 'const' is a important keyword to avoid bugs.

Declaring item of some kind of game, it will be like this.

class Item
{
    int _count;
    std::string _name;

public:
    Item(std::string const& name, int count)
    :_name(name), _count(count) {}
    
    std::string const& Name() {
        return _name;
    }
    int Count() {
        return _count;
    }
};

And let's implement a function for print Item.

// take reference to avoid copying object, and set const to avoid modifying that.
void PrintItem(Item const& item)
{
    std::cout << "name: " << item.Name() << " count:" << item.Count();
}
This is good idea to set 'const' for read-only reference. It prevents to modify data unintendedly. But the code above gets compile-time error.
error: passing 'const Item' as 'this' argument of 'const string& Item::Name()' discards qualifiers [-fpermissive]
error: passing 'const Item' as 'this' argument of 'int Item::Count()' discards qualifiers [-fpermissive]
Compiler says calling Item::Name() and Item::Count() may modify the internal data of Item. We humans know the Item::Name() and Item::Count() never modify data, but compiler doesn't. So we need to tell the compiler that Item::Name() and Item::Count() does not modify data like this.
class Item
{
    int _count;
    std::string _name;

public:
    Item(std::string const& name, int count)
    :_name(name), _count(count) {}
    
    std::string const& Name() const {   // 'const' after function name tells the function never modify internal data.
        return _name;
    }
    int Count() const {   // The same to above.
        return _count;
    }
};

Now we can compile and call the PrintItem() function.

What if a function declared as 'const' modifies internal data?
It gets compile-time error too.




What is copy constructor?

Copy constructor is used to copy instance.
We need to declare copy constructer when simple memory copying is undesirable.

For example, let's make variable length string class.

#include <iostream>
#include <string.h>

using namespace std;

class MyString
{
    char* str;
public:
    MyString() { str=nullptr; }
    ~MyString() { delete str; }

    void set(char const* src) {
        // delete existing memory and allocate enough new memory.
        delete str;
        str = new char[strlen(src)+1];    // danger code... don't care here.
        strcpy(str, src);
    }
    char* const get() {
        return str;
    }
};

void test(MyString copy_of_s)
{
    copy_of_s.set("abc"); // step 3
}

int main()
{
    MyString s;
    s.set("hello");    // step 1
    cout << s.get() << endl;   // output: hello
    test(s);           // step 2
    cout << s.get() << endl;   // step 4 -- what will be printed?
}

This class has no copy constructer yet.
What will happne on step 4??
Our program intend to print "hello". because test() takes a copy of MyString, so 's' will not be changed by the function.
But actually this program accesses dangling pointer on step 4.

Here describe the memory status step by step.

step 1 --- create MyString instance and set "hello".


step 2 --- copy instance by calling function


step 3 --- set "abc" to copied instance.


At this point, the memory storing string "hello" is deleted by MyString::set() funciton.
So at the step 4 MyString::get() function accesses the deleted memory.

To solve the problem, we should declare copy constructor.

class MyString
{
    char* str;
public:
    MyString() { str=nullptr; }
    ~MyString() { delete str; }

    // copy constructor.
    // take reference to source instance, allocate new memory and copy string holded by src.
    MyString(MyString const & src) {
        this->str = new char[strlen(src.str)+1];
        strcpy(this->str, src.str);
    }

    void set(char const* src) {
        // delete existing memory and allocate enough new memory.
        delete str;
        str = new char[strlen(src)+1];    // danger code... don't care here.
        strcpy(str, src);
    }
    char* const get() {
        return str;
    }
};

When calling test(), MyString(MyString const &src) is called.
Memory is managed properly, and say hello twice!



Wednesday, August 23, 2017

Enum with string

If you need enums and strings that are equivalent as that names, You can declare like this.

#define ENM \
E(AAA)\
E(BBB)

#define E(x) x,
enum {
    ENM
};
#undef E

#define E(x) #x,
const char* strs[] = {
    ENM
};
#undef E

int main() {
    cout << AAA << endl;          // 0
    cout << strs[AAA] << endl;    // AAA
    return 0;
}

Tuesday, August 22, 2017

Reducing #includes in header

In C++, '#include' is an easy way to import other module.

But we need to consider the side-effect of #include. It may be big deal some time.

for example,
file: module_a.hpp
------------------------------------------
class ModuleA
{
    ...
    ...
};
file: module_a.cpp
------------------------------------------
#include "module_a.hpp"
...
...
file: module_b.hpp
------------------------------------------

#include "module_a.hpp"

class ModuleB
{
    ModuleA module_a;
    ...
    ...
};
file: module_b.cpp
------------------------------------------
#include "module_b.hpp"
...
...

file: main.cpp
------------------------------------------

#include "module_b.hpp"

int argc, char *argv[])
{
    ModuleB module_b;

    ...
    ...
}

...What's wrong??
C++ programmer always do like this.

Then let me show another approach.

file: module_a.hpp
------------------------------------------
class ModuleA
{
    ...
    ...
};
file: module_a.cpp
------------------------------------------
#include "module_a.hpp"
...
...

file: module_b.hpp
------------------------------------------
#include <memory>
class ModuleA;

class ModuleB
{
    std::unique_ptr<ModuleA> module_a;
    ...
    ...
};
file: module_b.cpp
------------------------------------------
#include "module_b.hpp"
#include "module_a.hpp"

...
...

file: main.cpp
------------------------------------------
#include "module_b.hpp"

int argc, char *argv[])
{
    ModuleB module_b;

    ...
    ...
}

The point is the position of '#include "module_a.hpp"'.
Include-dependencies are different.

In the first pattern, the dependency is,
main.cpp --> module_b.hpp --> module_a.hpp
module_b.cpp --> module_b.hpp --> module_a.hpp
module_a.cpp --> module_a.hpp

The second pattern,
main.cpp --> module_b.hpp
module_a.cpp --> module_a.hpp
module_b.cpp --> module_b.hpp
             --> module_a.hpp

If module_a.hpp is modified, the first pattern needs all files to be re-compiiled.
The second pattern needs module_a.cpp, module_b.cpp to be re-compiled.

It looks a small matter in this example, but in big project, it will make a significant difference of buiding time.

Generally, it's not recommended including file in header.
except these cases.
- Headers of library. It will not be modified in future.
- Templates. We need to include template to instanciate the actual declaration.
- Parent class to inherit.







What is function object ?

std::function is a class for 'function object'.
This is powerful way to represent predicator.

Let's see how to use it.

First, I show a sample with no 'std::function's.

// Predicator class(i.e., has operator() ) which take int for argument and returns int by adding it's internal value.
class Adder
{
public:
    int to_add;
    int operator()(int a) {
        return a + to_add;
    }
};

// Another predicator doing multiply.
class Multiplier
{
public:
    int to_mul;
    int operator()(int a) {
        return a * to_mul;
    }
};

// Some class having std::vector<int>
class Foo
{
    std::vector<int> vec;
public:

    // apply predicator.
    template <typename T>
    void apply(T pred) {
        for(int& elm : vec) {
            elm = pred(elm);         //the predicator is intended to have 'int operator(int)'
        }
    }
};

// some function
void Bar(Foo& foo, int to_add, int to_mul)
{
    Adder adder;
    adder.to_add = to_add;
    foo.apply(adder);   // add for each int

    Multilier multi;
    multi.to_mul = to_mul;
    foo.apply(multi);   // mulply for each int
}

We need to declare predicator class for each calcuration( adding and multipling )
Next, let's do this using std::function.

// Some class having std::vector<int>
class Foo
{
    std::vector<int> vec;
public:

    // apply predicator.
    void apply(std::function<int(int)> func) {  //take std::function which take int as argument, and returns int.
        for(int& elm : vec) {
            elm = func(elm);      // call the func
        }
    }
};

int add(int a, int to_add) { return a+to_add; }
int mul(int a, int to_mul) { return a*to_mul; }

void Bar(Foo& foo, int to_add, int to_mul)
{
    //std::bind() makes std::function instance holding function pointer with internal values.
    //std::placeholders::_1 means the argument will passed by caller.

    std::function<int(int)> adder = std::bind(&add, std::placeholders::_1, to_add);
    //so, 'adder' has a pointer to function 'add' and a value 'to_add'.
    //first argument will be passed by the caller.

    foo.apply(adder);   // add 2 for each int

    //std::function to multiply.
    std::function<int(int)> multi = std::bind(&mul, std::placeholders::_1, to_mul);

    foo.apply(multi);   // mulply 3 for each int
}

std::function can have any value in it. and has operator() of specified type signature.
for example,
std::function<int(float)>  -  function object that take float for arugment, returns int.
std::function<std::string(double, int)>   - function object that take double and int, returnts std::string

Next, let's make this example shorter with lambda expression.

// Some class having std::vector
class Foo
{
    std::vector<int> vec;
public:

    // apply predicator.
    void apply(std::function<int(int)> func) {  //take std::function which take int as argument, and returns int.
        for(int& elm : vec) {
            elm = func(elm);      // call the func
        }
    }
};

void Bar(Foo& foo, int to_add, int to_mul)
{
    // lambda expression can make function object in line.
    std::function<int(int)> adder = [to_add](int a) -> int { return a+to_add; };

    foo.apply(adder);   // add 2 for each int

    std::function<int(int)> multi = [to_mul](int a) -> int { return a*to_mul; };

    foo.apply(multi);   // mulply 3 for each int
}

With std::function, we can easily declare predicator and make the program more flexible.







Saturday, August 19, 2017

Organizing classes 3/3

Modularized class


In previous post, I show the design of composite class.
It looks almost nice but it' a bother to write/use accessor functions to each component.

The third idea here I introduce is something I call 'modularized class'.

class Object
{
public:
    virtual ~Object() {} // make Object polymorphic.
};

// component classes deriving Object 'virtual'ly.
class Input : public virtual Object
{
    ...
};
class AIParam : public virtual Object
{
    ...
};
class Position : public virtual Object
{
    ...
};
class Health : public virtual Object
{
    int health;
public:
    void apply_damage(int damage) {

        // when this object inherits TimeStatus, calcurate damage by the status
        TimeStatus* s = dynamic_cast<TimeStatus*>(this);
        if( s ) {
            // do some culcuration.
        }
        health -= damage;
    };
};
class TimeStatus : public virtual Object
{
    ...
};

template <typename... Modules>
class ModularObject : public Modules...
{
};

// Player, Enemy, Obstacle class inherits each component class.
// template class ModularObject is used for utility.
typedef ModularObject<Input, Position, TimeStatus, Health> Player;
typedef ModularObject<AIParam, Position, TimeStatus, Health> Enemy;
typedef ModularObject<Position,Health> Obstacle;

// use like this. (using template)
template <typename T>
void attack(int damage, T* obj)
{
    // when obj does not inherit Health, this gets compile error.
    obj->apply_damage(damage);
}

// or use dynamic_cast
void attack(int damage, Object* obj)
{
    // when obj does not inherit Health, nothing happens.
    Health* h = dynamic_cast<Health*>(obj);
    if( h ) {
        h->apply_damage(damage);
    }
}

This approach uses multiple inheritance. and virtual inheritance which solves 'diamond problem'.

It's easy to add/remove features, and can access components directory.

I think this is the best solution for organizing class for game object.



Organizing classes 2/3

Using composition

In the previous post, we tried to implement some features of game object by class inheritance, but it was not so good for maintenance.

Now, we will try to solve this problem by 'composite class'

// base class has interface to get all components, returning nullptr by default.
class Object
{
public:
    virtual Input* input() { return nullptr; }
    virtual AIParam* ai_param() { return nullptr; }
    virtual Position position() { return nullptr; }
    virtual Health* health() { return nullptr; }
    virtual TimeStatus* time_status() { return nullptr; }
};

// player class has actual component and returns its pointer.
class Player : public Object
{
    Input input;
    Position position;
    Health health;
    TimeStatus time_status;    
public:
    virtual Input* input() { return &input; }
    virtual Position position() { return &position; }
    virtual Health* health() { return &health; }
    virtual TimeStatus* time_status() { return &time_status; }
};

// enemy class is same as Player except first field.
class Enemy : public Object
{
    AIParam ai_param;
    Position position;
    Health health;
    TimeStatus time_status;    
public:
    virtual AIParam* ai_param() { return &ai_param; }
    virtual Position position() { return &position; }
    virtual Health* health() {  return &health; }
    virtual Health* time_status() { return &time_status; }
};

// obstacle class has Position and Health.
class Obstacle : public Object
{
    Position position;
    Health health;    
public:
    virtual Position position() { return &position; }
    virtual Health* health() {  return &health; }
};

// Health component, implements apply_damage()
class Health
{
    Object* owner;
    int health;
public:
    void apply_damage(int damage) {
        if( owner->time_status() ) {
            // calc damage by status;
        }
        health -= damage;
    }
};

In this design, A derived classes is composed by feature classes(i.e., component) and has accessor function to each component.
Each component has pointer to Object in order to access other component.

for example, attack() function will look like this.
void attack(int damage, Object* obj)
{
    if( obj->health() ) {
        obj->health()->apply_damage(damage);
    }
}

Comparing previous design(using inheritance), it's easier to add/remove features.
But accessing components by getter function is not looks pretty.

Now, I propose an other idea in next post.




Tuesday, August 15, 2017

Organizing classes 1/3

In most of game programs, It is the common problem that how to organize classes.

We have a class Player, Enemy, Obstacle, Bullet, ...and these objects' features are partially same, and partially different.And if it is a online game, it updates repeatedly.

Using inheritance


Let's dive into code.

// the Base class of all. has position data.
class Object
{
    int pos_x;
    int pos_y;
};

// Player class has input data, inherits Object.
class Player : public Object
{
    float input_dir;
};

// Enemy class has some kind of AI parameter, also inherites Object.
class Enemy : public Object
{
    int ai_param;
};

// Obstacle class has no data here, and inherits Object.
class Obstacle : public Object
{
};
Here we declare Object, Player, Enemy, Obstacle class.
In the sense of 'Inheritance', this organization seems meaningful.

Next, let's think to add data 'poisoned' which is bool value and represents the object get poisoned.
Well, what kind of object can get poisoned??
In this case, Player and Enemy. Obstacle can not get poisoned.

// Player class has input data, inherits Object.
class Player : public Object
{
    float input_dir;
    bool poisoned;
};

// Enemy class has some kind of AI parameter, also inherits Object.
class Enemy : public Object
{
    int ai_param;
    bool poisoned;
};

// Obstacle class has no data here, and inherits Object.
class Obstacle : public Object
{
};

Here we met some trouble... 'bool poisoned' is duplicated. This means poison-related implementation will duplicate too.
And in the future, when it comes to add 'cursed' or 'paralyzed', we will get same problem.

One idea to solve this problem is to create new base class.

//Living Object may got poisoned, paralyzed, ... and some other status.
class LivingObject : public Object {
{
    bool poisoned;
    bool paralyzed;
    ...
};

class Player : public LivingObject
{
    float input_dir;
};

class Enemy : public LivingObject
{
    int ai_param;
};

class Obstacle : public Object
{
};

Creating new class and make existing classes inherit the new class...easy! ...really?

Additionally, what if we need to declare data 'health'?
Ok, LivingObject has health.....No. It's not good. because we need 'health' for Obstacles in order to get destroyed by others.

Well, how can we re-organize the class tree !?
It's painful to re-organize the class tree. And if it's already released product, it will take big risk.

=> to be continued to next post.


Sunday, August 13, 2017

What is OOP(Object Oriented Programmming)?? -- the real meaning in C++ - 2/2

In previous post, We learn meanings of Class, Methods in C++,which is the set of data and how to process that.

And see the simple video game's Player class in C++ like

class Player
{
private:
    int pos_x;
    int pos_y;    

public:
    void apply_input(float direction);
    void move_to(int x, int y);
};

Ok next, we will make class Enemy.

class Enemy
{
private:
    int hate;
    int pos_x;
    int pos_y;    

public:
    void apply_hate(int hate);
    void move_to(int x, int y);
};

Class Enemy does not require 'apply_input()' method because it will not move by joystick input.
And Enemy has hate data(declared as int to make it simple), which will used for enemy's behaviour.

mmm... It seems to be OK, but the Player and Enemy has same data and methods.
It's waste of codes.

Let's think about 'pos_x' and 'pos_y'.
These are attributes of all object in the game.
So we declare Object class which have position data and related method.

class Object
{
private:
    int pos_x;
    int pos_y;
public:
    void move_to(int x, int y);
};

and the class Player and Enemy 'Inherits' the class Object.

class Player : public Object
{
public:
    void apply_input(float direction);
};

class Enemy : public Object
{
private:
    int hate;
public:
    void apply_hate(int hate);
};

Inheritance in C++ means addition of data and methods.
In this example, Object has position of object.
And in addition, Player has method 'apply_input', Enemy has data 'hate' and a method 'apply_hate()'.

Inheritance is usable when some code is common in some classes.



What is OOP(Object Oriented Programmming)?? -- the real meaning in C++ - 1/2

Object Oriented Programming(OOP) -- when you start to learning programming, this may the first paradigm you will meet. And most explanations of OOP I saw in books or websites, does not explain the real meaning of OOP.

You may see this sort of explanation.
Animals ----- Birds
         +- Fishes
         +- Mammals
'Animals','Fishes','Birds','Mammals' are Class. 'Animals' is a parent Class of other ones. and Birds has a method of 'fly', Fishes has a method of 'swim', and so on.

With this kind of explanation, You can understand the meanings of words 'Class' or 'Method' in abstract concept. But you can't learn the real meanings of C++.

In C++, the 'Class' means the set of data and how to process that.
'How to process that?' is the Class Method.

Let's see some example.
In video game, a player is a typical object.
the Player class is declared like this.

class Player
{
private:
    int pos_x;
    int pos_y;    

public:
    void apply_input(float direction);
    void move_to(int x, int y);

};

You see the data 'pos_x','pos_y' and methods 'apply_input()','move_to()'.
As you can easily understand, 'pos_x' and 'pos_y' means position of the player.
The method 'apply_input()' applies input data of joystick, 'move_to()' moves the player to specified position.

Simple, isn't it !?

For comparision, let's see the C language implementation of this Player.

struct Player
{
    int pos_x;
    int pos_y;
};

void apply_input(struct Player*, float direction);
void move_to(struct Player*, int x, int y);

In C, struct can not have methods. so we must declare functions outside of the struct, receiving pointer to the struct.

so, class in C++ is the set of data and how to process it.

Would you like to learn more?
Visit the next post.

It&#39;s magic! std::bind

'std::bind' is a powerful helper for working around 'std::function'. 'std::bind' makes a instance of 'std::fun...