fork download
  1. /** Oliveri Dario's article code for
  2.   gameprog.it
  3. */
  4. #include <iostream>
  5. #include <exception>
  6.  
  7. #define IMAGE_MOVE_SEMANTICS 1
  8.  
  9. class MismatchingSize: public std::exception{
  10. public:
  11.  
  12. };
  13.  
  14. class Image{
  15.  
  16. unsigned char * buffer = nullptr;
  17. std::size_t size = 0;
  18.  
  19. void copyFrom( const Image & o){
  20. for( std::size_t i = 0; i<size; i++)
  21. buffer[i] = o.buffer[i];
  22. std::cout<<"Copia eseguita"<<std::endl;
  23. }
  24.  
  25. void realloc(std::size_t s){
  26. if(buffer)
  27. delete buffer;
  28.  
  29. if(s>0){
  30. buffer = new unsigned char[s];
  31. std::cout<<"Allocazione eseguita"<<std::endl;
  32. }
  33. }
  34.  
  35. public:
  36.  
  37. Image(){ }
  38.  
  39. Image( std::size_t s):size(s) {
  40. realloc(s); // allocazione
  41. }
  42.  
  43. #ifdef IMAGE_MOVE_SEMANTICS
  44. Image( Image &&o){
  45. std::cout<<"Move Constructor chiamato!"<<std::endl;
  46. buffer = o.buffer; //copio i dati da "o"
  47. size = o.size;
  48.  
  49. o.buffer = nullptr; //resetto "o"
  50. o.size = 0;
  51. }
  52.  
  53. Image& operator = ( Image &&o){
  54. std::cout<<"Move Assignment chiamato!"<<std::endl;
  55. buffer = o.buffer; //copio i dati da "o"
  56. size = o.size;
  57.  
  58. o.buffer = nullptr; //resetto "o"
  59. o.size = 0;
  60. return (*this);
  61. }
  62. #endif
  63. Image( const Image &o): Image(o.size){ // allocazione
  64. copyFrom(o);
  65. }
  66.  
  67. Image& operator = ( const Image &o){
  68. size = o.size;
  69. realloc(size);
  70. copyFrom(o);
  71. return (*this);
  72. }
  73.  
  74. bool drawAColor( std::size_t s, unsigned char color ){
  75. size = s;
  76. realloc(s);
  77. for( std::size_t i = 0; i<s; i++)
  78. buffer[i] = color;
  79.  
  80. return true;
  81. }
  82.  
  83. friend Image operator+( const Image &A, const Image &B){
  84. if(A.size!=B.size)
  85. throw MismatchingSize();
  86.  
  87. Image image(A.size);
  88. for( std::size_t i = 0; i<A.size; i++)
  89. image.buffer[i] = A.buffer[i]+B.buffer[i];
  90.  
  91. std::cout<<"Somma eseguita"<<std::endl;
  92.  
  93. return image;
  94. }
  95.  
  96. void print() const{
  97. for( std::size_t i = 0; i<size; i++)
  98. std::cout<<(int)buffer[i]<<" ";
  99. std::cout<<std::endl;
  100. }
  101. };
  102.  
  103. void test1(){
  104. std::cout<<"Test 1:"<<std::endl;
  105. Image a,b;
  106. a.drawAColor(5,10);
  107. b.drawAColor(5,17);
  108.  
  109. Image c;
  110. c = a+b; //scrittura apparentemente innocua e "leggera"
  111.  
  112. std::cout<<"\nImmagine a:"<<std::endl;
  113. a.print();
  114. std::cout<<"Immagine b:"<<std::endl;
  115. b.print();
  116. std::cout<<"Immagine c:"<<std::endl;
  117. c.print();
  118. }
  119.  
  120. void test2(){
  121. std::cout<<"\n\nTest 2:"<<std::endl;
  122. Image a,b;
  123. a.drawAColor(5,10);
  124. b.drawAColor(5,17);
  125.  
  126. Image c;
  127. c = (a+b)+(a+b); //scrittura apparentemente innocua e "leggera"
  128.  
  129. std::cout<<"\nImmagine a:"<<std::endl;
  130. a.print();
  131. std::cout<<"Immagine b:"<<std::endl;
  132. b.print();
  133. std::cout<<"Immagine c:"<<std::endl;
  134. c.print();
  135. }
  136.  
  137. int main(){
  138. test1();
  139. test2();
  140. return 0;
  141. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
Test 1:
Allocazione eseguita
Allocazione eseguita
Allocazione eseguita
Somma eseguita
Move Assignment chiamato!

Immagine a:
10 10 10 10 10 
Immagine b:
17 17 17 17 17 
Immagine c:
27 27 27 27 27 


Test 2:
Allocazione eseguita
Allocazione eseguita
Allocazione eseguita
Somma eseguita
Allocazione eseguita
Somma eseguita
Allocazione eseguita
Somma eseguita
Move Assignment chiamato!

Immagine a:
10 10 10 10 10 
Immagine b:
17 17 17 17 17 
Immagine c:
54 54 54 54 54