Urbano's Blog
Words from Alejandro U. Alvarez
Words from Alejandro U. Alvarez
Mar 20th
You probably know that the ostream and istream operators (<< and >>) can be overloaded for your custom classes, but let's take a look at how to overload them for template classes like the vector class.
The way this is done is by placing the keyword template before the function. After template we have to specify the type, or we can use a generic type T. Let me illustrate this with an example:
// Overloading for a template of type int. For example vector<int> template<int> myFunction(){} // Overloading for any type template<typename T> myFunction(){}
Alright so now that you know how to overload a template function, let's see how to overload them for the ostream and istream operators.
For this example I will assume we are working with the STL Vector library, and the way I will modify the operators is the following:
Let's see those functions:
template<typename T> ostream & operator < <(ostream & o,vector<T> & v){ int s = v.size(); o < < s << endl; for(int i=0;i<s;i++){ o << v[i] << endl; } return o; } template<typename T> istream & operator >>(istream & i,vector<t> & v){ int s; i >> s; T holder; for(int a=0;a<s ;a++){ i >> holder; v.push_back(holder); } return i; }
The only thing to take into account here is the holder variable I have created in the istream overloaded operator. Instead of directly using i >> v[a]; because that would throw an error, I created a variable holder of type T (The same as the vector) and then we "hold" the vector element before adding it to the vector v.
Notice that in the istream operator we don't create the vector and then return it, because we already have it's reference in v. We use push_back because v could have no elements.
Let me show you a rather simple main using this two operators with two vectors of type int and float to show you that it works with any type of data.
#include <iostream> #include <vector> using namespace std; template<typename T> ostream & operator < <(ostream & o,vector<T> & v){ int s = v.size(); o < < s << endl; for(int i=0;i<s;i++){ o << v[i] << endl; } return o; } template<typename T> istream & operator >>(istream & i,vector<t> & v){ int s; i >> s; T holder; for(int a=0;a<s ;a++){ i >> holder; v.push_back(holder); } return i; } int main(){ // Creamos dos vectores a y b vector<int> a; vector<float> b; // Usando el operador sobrecargado de extraccion les damos valores: cout < < "Please enter the size of a vector of integers, then its elements: "; cin >> a; cout < < "\nNow the same with floats for another vector: "; cin >> b; // Y finalmente los mostramos por pantalla: cout < < "\nThe values of both vectors (First the size then the elements): "; cout << "\nIntegers: " << a << "\nFloating point: " << b; cin.get();cin.get(); return 0; }
Mar 17th
I don't know whether this is useful or merely entertaining, but it is quite simple to display the character representation of any ASCII number in C++
We will use the static_cast function to perform this operation, converting from int to char.
Let me show you this sample program that does just that (Looping until you enter 0)
#include <iostream> using namespace std; int main(){ int r; cout < < "Enter a number to see its character: \n" << "Number: "; cin >> r; while(r!=0){ cout < < "\nCharacter: " << static_cast<char>(r); cin.get(); cout < < "\nNumber: "; cin >> r; } return 0; }</iostream>
As you can see we simply ask for a number, and while that number is not 0 we keep on asking for more, as well as displaying its character representation by using the static_cast function.
Hope you enjoyed this
Alex
Mar 17th
As you might know, when we develop a simple program that runs in the system console, using the standard library iostream, we might want to have special ways of displaying a class object.
You have probably heard of the istream and ostream operators (<< and >>), we can use overloading to change their behaviour.
Since they are not functions from our class, we must use a special keyword, friend. A friend function is neither public or private, our class doesn't control it's scope. They are classes that don't belong to a class, but have access to its private members.
Let's create a simple class to demonstrate this:
class simple{ int a,b; public: friend ostream & operator < <(ostream & o, simple & s){ o << s.a << " " << s.b; return o; } friend istream & operator >>(istream & i, simple & s){ i >> s.a >> s.b; return i; } };
This class has two private members, a and b. I haven't created any constructors as we don't really need them for the example. We will change the values of a and b using the input operator >> and we will display them using the output operator <<
How the istream and ostream operators work is quite simple actually. Declaring them friend gives them direct access to private members a and b. But since they don't belong to the class we must pass them a reference to the object from the class simple we want to modify: simple & s. The other parameter is the reference to the i/o stream itself, all our modifications will be "stored" in that reference and then returned.
Let me show you a basic main to show it in use:
main(){ simple obj; cin >> obj; cout < < "\nDisplay my simple object: "; cout << obj << endl; system("pause"); return 0; }
In this sample main we instantiate simple in the object obj, and we then call the input operator >> to give a and b some values.
After that we display the values using the output operator <<.
This simple program generates the following output (Imagine I enter 2 and 3 as input):
2 3 Display my simple object: 2 3
If you want the full working code:
#include <iostream> using namespace std; class simple{ int a,b; public: friend ostream & operator < <(ostream & o, simple & s){ o << s.a << " " << s.b; return o; } friend istream & operator >>(istream & i, simple & s){ i >> s.a >> s.b; return i; } }; main(){ simple obj; cin >> obj; cout < < "\nDisplay my simple object: "; cout << obj << endl; system("pause"); return 0; }
Well I hope you enjoyed this and understood it correctly
If you have any problems or suggestions feel free to comment below,
Alex
Mar 16th
If you know nothing about classes in C++ you should probably go read a bit on that, although if you know Java or a similar OO language you can go ahead.
In C++, as with most modern OO languages we have encapsulation, inheritance, and polymorphism. I won't go into much detail as this is just a quick reference on inheritance hierarchy and priorities.
Skip this if you already know, I just want to make sure you can follow me here. Basically a class can inherit methods and attributes from a parent class. Why would we want to do this? Well, to avoid extra work, which is the main priority of every coder!
We will start with public inheritance. So let's start with our parent class car
#include <iostream> using namespace std; class car{ bool engine, roof; public: car(); car(int p) : passengers(p){}; car(int p,int p1); bool hasEngine()const{ return roof; } bool hasRoof()const{ return roof; } int maxP()const{ return passengers; } protected: int price; int passengers; }; car::car(){ engine=roof=true; passengers=5; } car::car(int p,int p1){ passengers=p; price = p1; }
As you can see I have added some attributes and methods as well as two constructors for testing purposes.
Each car has an engine (Or not), can have roof or be convertible (roof=false) and have different passenger count and price.
I've set the price and passengers as protected because when a class inherits from a parent class, it will be able to modify protected attributes. Although from the rest of the code they will act as private.
Now the good thing about inheritance is that we can add, modify and reuse the code from car. Let's say we want to have sports cars, which have some differences with normal cars. Let's imagine sports cars have a new attribute that is racing (true or false)
So now I will create a new class, that will inherit from car. After that we will be able to start testing,
class sportsCar : public car{
bool racing;
public:
sportsCar();
};
sportsCar::sportsCar(){
car::passengers=2;
}
Now to see what happens, let's do a simple main with a couple constructors:
(Note: This is the full code)
#include <iostream>
using namespace std;
class car{
bool engine, roof;
public:
car();
car(int p) : passengers(p){};
car(int p,int p1);
bool hasEngine()const{ return roof; }
bool hasRoof()const{ return roof; }
int maxP()const{ return passengers; }
protected:
int price;
int passengers;
};
car::car(){
engine=roof=true;
passengers=5;
}
car::car(int p,int p1){
passengers=p;
price = p1;
}
class sportsCar : public car{
bool racing;
public:
sportsCar();
};
sportsCar::sportsCar(){
car::passengers=2;
}
int main(){
car myCar(5,20000);
cout << "Normal car, passengers: " << myCar.maxP();
sportsCar ferrari;
cout << "\nSports car, passengers: " << ferrari.maxP();
cin.get();
return 0;
}
The output of this would be:
Normal car, passengers: 5 Sports car, passengers: 2
For more information on class inheritance, check out this guide by Robert I. Pitts
Mar 11th
I actually think that we the developers need IE, it is like the bad guy in an action movie, the good guy wouldn't have a life without him, although sometimes you really wish it never existed! Haha just kidding, we all wish it didn't exist... But well, there are some times when we need something to work, we need it fast, and we just don't have time to care for the standards at that moment. For those times, we can use a simple trick like this:
This is probably the simplest tip, you can use underscores preceding style definitions to set them as comments... for all good browsers out there, except of course IE. This way you can easily define specific IE rules by putting an underscore before the style.
#underscore{ width:300px; _width:320px; /* This rule is only for IE */ }
This way we can easily add a different width, padding, or anything to an element in order to "get it right"
Now we are not going to do that with every single rule we need fixed! When we are going to fix more things, it's much better to put the fixes in a different stylesheet, and link it using a conditional statement. Basically, we want only IE6 for example to use those fixes, how is that done?
<!--[if lte IE 6]> <link media="screen" rel="stylesheet" href="something.css" /> <![endif]-->
But this doesn't validate! We need to find a solution then, and it is not as hard as one could think
We are going to include that, inside another conditional comment, but this time inside one that is valid! So we would write it as follows:
<!--[if IE]><![if lte IE 6]><![endif]--> <link media="screen" rel="stylesheet" href="something.css" /> <!--[if IE]><![endif]><![endif]-->
Now it validates! We have achieved using valid conditional comments to do this! I will now explain a bit more about these and how they work:
You're smart (I hope) So let's race through this, conditional comments allow you to tell the browser to use some parts of your html only if a specific version is running (Or not) Let me show you the options we have: (Please note that this is the html valid version for each of them)
We also have some keywords that will allow for more control:
For more information on conditional comments check out this guide by Manfred Staudinger