/** Oliveri Dario's article code for
gameprog.it
*/
#include <iostream>
#include <exception>
#define IMAGE_MOVE_SEMANTICS 1
class MismatchingSize: public std::exception{
public:
};
class Image{
unsigned char * buffer = nullptr;
std::size_t size = 0;
void copyFrom( const Image & o){
for( std::size_t i = 0; i<size; i++)
buffer[i] = o.buffer[i];
std::cout<<"Copia eseguita"<<std::endl;
}
void realloc(std::size_t s){
if(buffer)
delete buffer;
if(s>0){
buffer = new unsigned char[s];
std::cout<<"Allocazione eseguita"<<std::endl;
}
}
public:
Image(){ }
Image( std::size_t s):size(s) {
realloc(s); // allocazione
}
#ifdef IMAGE_MOVE_SEMANTICS
Image( Image &&o){
std::cout<<"Move Constructor chiamato!"<<std::endl;
buffer = o.buffer; //copio i dati da "o"
size = o.size;
o.buffer = nullptr; //resetto "o"
o.size = 0;
}
Image& operator = ( Image &&o){
std::cout<<"Move Assignment chiamato!"<<std::endl;
buffer = o.buffer; //copio i dati da "o"
size = o.size;
o.buffer = nullptr; //resetto "o"
o.size = 0;
return (*this);
}
#endif
Image( const Image &o): Image(o.size){ // allocazione
copyFrom(o);
}
Image& operator = ( const Image &o){
size = o.size;
realloc(size);
copyFrom(o);
return (*this);
}
bool drawAColor( std::size_t s, unsigned char color ){
size = s;
realloc(s);
for( std::size_t i = 0; i<s; i++)
buffer[i] = color;
return true;
}
friend Image operator+( const Image &A, const Image &B){
if(A.size!=B.size)
throw MismatchingSize();
Image image(A.size);
for( std::size_t i = 0; i<A.size; i++)
image.buffer[i] = A.buffer[i]+B.buffer[i];
std::cout<<"Somma eseguita"<<std::endl;
return image;
}
void print() const{
for( std::size_t i = 0; i<size; i++)
std::cout<<(int)buffer[i]<<" ";
std::cout<<std::endl;
}
};
void test1(){
std::cout<<"Test 1:"<<std::endl;
Image a,b;
a.drawAColor(5,10);
b.drawAColor(5,17);
Image c;
c = a+b; //scrittura apparentemente innocua e "leggera"
std::cout<<"\nImmagine a:"<<std::endl;
a.print();
std::cout<<"Immagine b:"<<std::endl;
b.print();
std::cout<<"Immagine c:"<<std::endl;
c.print();
}
void test2(){
std::cout<<"\n\nTest 2:"<<std::endl;
Image a,b;
a.drawAColor(5,10);
b.drawAColor(5,17);
Image c;
c = (a+b)+(a+b); //scrittura apparentemente innocua e "leggera"
std::cout<<"\nImmagine a:"<<std::endl;
a.print();
std::cout<<"Immagine b:"<<std::endl;
b.print();
std::cout<<"Immagine c:"<<std::endl;
c.print();
}
int main(){
test1();
test2();
return 0;
}