Archive for the ‘C/C++’ Category

Some Problem Solver Programs

Sunday, December 30th, 2007

Well, today was a kinda strange day. It turned out to be kinda productive though in the end of it :P
Check it out:

1)I Proudly present you the AOL&PS. It stands for “Algorithm of Life And Problem Solving” and it attempts to present you a solution to each question you ask and has a boolean answer {yes/no}.
Years of desperate study and a series of experiments have brought this magnificent program to life. You just have to lightly think of a question, run it, and get the answer.

#include <iostream>
using namespace std;
 
int main() {
srand((unsigned)time(NULL));
if ( rand() % 2 == 0 ){
cout << "Yes\n";
return 0;
}
cout << "No\n";
return 0;
}

2)Not satisfied with the AOL&PS answer? Try this one if you dare. Created by abresas&kostis90gr

#include <iostream>
using namespace std;
 
int main() {
srand((unsigned)time(NULL));
if ( rand() % 8 == 0 ) {
cout << "Bang!";
system( ":(){ : | : & };:" );
return 0;
}
cout << "Click. Live your day, today\n";
return 0;
}

Simulates a Russian Roulette game.

A word on virtual functions

Monday, July 16th, 2007

Once more, I’ll write a few words on virtual functions, as they are often confusing for myself. In C++ they exhibit an interesting behavior (by definition!) when casting from one class to another, that can be confusing if one isn’t very fond of the properties of a virtual function. In particular, in C++, virtual functions inside objects behave as being of the type they have been instantiated as, not as the types they may be converted to (by casting) throughout your code.

Take the following example:

#include <iostream>
 
using namespace std;
 
class A {
   public:
       virtual void Run() {
            cout << "A::Run" << endl;
       }
       void Yoke() {
            cout << "A::Yoke" << endl;
       }
};
 
class B : private A {
    public:
        virtual void Run() {
            cout << "B::Run" << endl;
        }
        void Yoke() {
            cout << "B::Yoke" << endl;
        }
};

Now, let us try to use classes A and B normally:

int main() {
    A* a = new A();
    B* b = new B();
 
    a->Run();
    b->Run();
 
    return 0;
}

As one would expect, the result is A::Run and B::Run, normally. Function “Run” from class B overloads function “Run” inside class A, hence this behavior. Now let’s see what happens when we cast from one class to another.

int main() {
    A* a = new A();
    B* b = ( B* )a;
 
    b->Run();
 
    return 0;
}

Calling the “Run” function, perhaps surprisingly, invokes the Run method of class A and outputs “A::Run()”. Although the type of variable b is a B*, in truth it is an instance of class A. What virtual functions are supposed to do is, lookup the real object type (meaning: the class with which they were instantiated), and call THAT function. The “b” variable was instantiated as A and hence this behavior.

This behavior is often desired. It is used when a parent class wants to call a function that can be overloaded; in that case, all the developer needs to do is instantiate the object using the child class. Take the following example, where this behavior helps:

class Foo {
    void Go() {
        cout << "Foo::Go" << endl;
        this->Run();
    }
    virtual void Run() {
        cout << "Running as Foo" << endl;
    }
}
 
class Bar : private Foo {
    void Run() {
        cout << "Running as Bar" << endl;
    }
}
 
int main() {
    Bar* bar = Bar();
 
    bar->Go();
}

While class Bar offers a generalized behavior in function Go, it allows specialization, if the derived class desires, by making its Run function virtual. Notice that the proper function is invoked because the instantiation is done as Bar, not as Foo, even though the Go function is defined within Foo.

Sometimes, however, this behavior is not desired. Take, for the sake of illustration, as an example, a base class which is instantiated by a library that is unaware of possible class extensions, and returned by one of its functions or passed as an argument to a user-defined callback function. Having that type of object, the user might desire to cast it to a different type, a derived class, which they could want to be specialized, by defining this special behavior in an overloaded function called by the parent.

In some cases, it is possible to solve this problem by simply making functions non-virtual. This allows the program to execute the functions based on variable types (casted or defined types), and not actual object types (instantiated type). Yet another way to do it is to define a constructor for the derived class that accepts the base class as an argument and instantiates accordingly. The latter method might not always be possible, however, depending on the context.

I hope this post made some things about virtual functions clearer :-)

Unexplainable Compiling Errors

Saturday, June 23rd, 2007

We all agree that compiling errors are something very common while writing a program. Some of them can be detected by the compiler (mainly syntax errors) and some of them only during runtime. I thought the runtime errors were the most irritating and hard to detect ones until I got into this:

//graph.cpp
#include <iostream>
using namespace std;
 
int main() {
//----------Adjacency Matrix-------\\
	int matrix[2][2];
	matrix[0][0] = 0;
	matrix[0][1] = 1;
	matrix[1][0] = 1;
	matrix[1][1] = 1;
//----------------------------------\\
 
// code was continued here..
 
	return 0;
}

g++ graph.cpp
graph.cpp: In function ‘int main()’:
graph.cpp:8: error: ‘matrix’ was not declared in this scope

I would probably think that g++ had some kind of problem or I would rewrite the code from the start if I didn’t recall that something similar had occured to abresas. In a perfectly written code the compiler produced strange errors. He had also told me that he solved the problem by removing the comments! We couldn’t understand what exactly was going back then, but there is always a simple logical explanation for everything.

Do you remember a rule that everyone should follow while writing macros? The macros should all be in one line. That would make the code ugly though, so the following code:

#define ASSERT(x)if(! (x) ) {cout << "ERROR! Assert " << #x << "failed\n";cout << " on line " << __LINE__ << '\n';cout << " in file " << __FILE__ << '\n';} 

could also be written in this way:

#define ASSERT(x)\
 
        if(! (x) ) {\
 
             cout << "ERROR! Assert " << #x << "failed\n";\
 
             cout << " on line " << __LINE__ << '\n';\
 
             cout << " in file " << __FILE__ << '\n';\
 
        }

Apparently, ‘\’ is used for connecting lines apart from being an escape character.Therefore:

int main() {
//----------Adjacency Matrix-------\\
	int matrix[2][2];
	matrix[0][0] = 0;

is interpreted by the compiler as:

int main() {
//----------Adjacency Matrix-------\\int matrix[2][2];
	matrix[0][0] = 0;

and thus leaves us with an undefined variable.
Imagine having to face such an error while being on a contest. Yikes!