Dubbi su costruttori copia e operatori di assegnazione

di il
12 risposte

Dubbi su costruttori copia e operatori di assegnazione

Salve a tutti, ho dei problemi riguardo il file .cpp che a quanto pare mi crea un loop infinito, forse non ho capito bene come allocare la memoria dinamicamente e l'uso dei distruttori e costruttori, in particolare non mi torna il il getPixel, il costruttore di copia e l'operatore di assegnazione, l'obiettivo dell'esercizio sarebbe proprio di sapersi destreggiare con quest'ultimi, grazie in anticipo a chi risponderà

ecco il testo
-si completi il codice del costruttore BitmapImage facendo in modo che se una delle dimensioni fornite dall'immagine è nulla o negativa allora la dimensione è impostata a 1
-si completi il distruttore per evitare memory teak
-si implementi il metodo getPixel in modo tale che se vengono richiesti pixel al di fuori delle dimensioni dell'immagine si renda un pixel i cui valori RGB sono (-1,-1,-1)
-si implementi costruttore di copia
-si implementi operatore di assegnazione
-si implementi un operatore di uguaglianza





FILE .h
#ifndef BITMAPIMAGE_H_
#define BITMAPIMAGE_H_

#include "RGBPixel.h"

class BitmapImage {
public:
	BitmapImage(int w, int h); // TODO check that w and h are >0. Minimum image size is 1x1
	BitmapImage(const BitmapImage& bm); // TODO implement a copy constructor
	virtual ~BitmapImage(); // TODO avoid memory leaks

	void setPixel(int x, int y, const RGBPixel& value);
	RGBPixel getPixel(int x, int y) const; // TODO: getting pixels outside of image return a RGBPixel with values (-1, -1, -1)

	bool operator==(const BitmapImage& rh); // TODO: implement
	BitmapImage& operator=(const BitmapImage& rh); // TODO implement an assignment operator

	int getWidth() const {
		return width;
	}
	int getHeight() const {
		return height;
	}

protected:
	int width, height;
	RGBPixel* bitmap;
};

#endif /* BITMAPIMAGE_H_ */


FILE .cpp
#include "BitmapImage.h"

BitmapImage::BitmapImage(int w, int h) : width(w), height(h) {
	// TODO check that w and h are >0. Minimum image size is 1x1
	if(w <= 0 && h <= 0) {
        width = 1;
        height = 1;
    }
    bitmap = new RGBPixel[width * height];
}

BitmapImage::~BitmapImage() {
	// TODO avoid memory leaks
	if(bitmap != nullptr)
	    delete[] bitmap;
}

// TODO implement a copy constructor
BitmapImage::BitmapImage(const BitmapImage& bm) {
    //shallow copy
    width = bm.width;
    height = bm.height;
    //deep copy
    if(bm.bitmap != nullptr){
        bitmap = new RGBPixel(*bm.bitmap);
        for (int i = 0; i < width * height; i++)
            bitmap[i] = bm.bitmap[i];
    }
    else
        bitmap = nullptr;
}


void BitmapImage::setPixel(int x, int y, const RGBPixel& value) {
	if ((x >= 0) && (x < width) && (y >= 0) && (y < height))
		bitmap[x + y * width] = value;
}

RGBPixel BitmapImage::getPixel(int x, int y) const {
	// TODO: getting pixels outside of image return a RGBPixel with values (-1, -1, -1)
    if ((x >= 0) && (x < width) && (y >= 0) && (y < height))
        return  bitmap[x + y * width];
    else
        return RGBPixel(-1,-1,-1);
}

// TODO implement an equality operator
bool BitmapImage::operator==(const BitmapImage& rh) {
    if(width != rh.width)
	    return false;
    if(height != rh.height)
        return false;
    //devo controllare anche tutto l'array bitmap
    for(int i = 0; i < width*height; i++)
        if(bitmap[i] != rh.bitmap[i])
            return false;
    return true;
}

// TODO implement an assignment operator
BitmapImage& BitmapImage::operator=(const BitmapImage& rh) {
    if(this != &rh){
        if(bitmap != nullptr)
            delete []bitmap;

        width = rh.width;
        height = rh.height;

        if(rh.bitmap != nullptr) {
            bitmap = new RGBPixel(*rh.bitmap);
            for (int i = 0; i < width * height; i++)
                bitmap[i] = rh.bitmap[i];
        }
        else
            bitmap = nullptr;
    }
	return *this;
}


12 Risposte

  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Nel costruttore di copia e operatore assegnamento questa riga
    
    bitmap = new RGBPixel(*bm.bitmap);
    
    non ha senso. Dev'essere
    
    bitmap = new RGBPixel[witdh * height];
    
    come nel costruttore.
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Ok perfetto, adesso mi torna il costruttore di copia e l'operatore di assegnazione e dovrebbe andare bene.

    Ho ancora problemi col costruttore per quanto riguarda la richiesta "check that w and h are >0. Minimum image size is 1x1" i

    ll file di tester mi dice hint: your code/tests do not correctly cover constructor: "check that height is >0. Minimum image size is 1x1", a me sembra sia giusto come ho fatto
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    La condizione è vera se e solo se sia w sia h sono <= 0.
    Questo significa che se w > 0, il compilatore non perde tempo a verificare se anche h > 0, quindi la condizione è falsa e tu corri il rischio di avere una w > 0 e una h <= 0.
    Le due condizioni devono essere verificate separatamente.
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Grazie per la risposta e per i consigli.
    Ho usato OR che fa sì che valga quando rispetta una delle due condizioni o entrambe, ma non torna lo stesso.
    il test mi restituisce "hint: your code/tests do not correctly cover constructor: check that width is >0. Minimum image size is 1x1"
    potrebbe essere che non stia inizializzando bene l'immagine 1x1?
    
    BitmapImage::BitmapImage(int w, int h) : width(w), height(h) {
    	// TODO check that w and h are >0. Minimum image size is 1x1
        if (w  < 0 || h < 0) {
            width = 1;
            height = 1;
        }
        bitmap = new RGBPixel[width * height];
    }
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Posto w == 0 e h == 10, la condizione diventa:
    if (0 < 0 || 10 < 0)
    ...

    ora 0 < 0 è vero o falso?
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Direi falso.
    Mi sono accorto di essermi dimenticato l'uguale, la condizione deve essere <= di zero.
    ho messo l'uguale ma non torno comunque, mi ridà lo stesso suggerimento il tester
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Premesso che esistono diversi modi per soddisfare la condizione, può darsi che il tester verifichi che le variabili poste a condizione siano proprio width e height, non w e h. Oppure che verifichi il verso dell'uguaglianza.
    Prova a scriverlo nel modo più bovino possibile.
    
    BitmapImage::BitmapImage(int w, int h) : width(w), height(h) {
       // TODO check that w and h are >0. Minimum image size is 1x1
       if (width > 0 && height > 0) 
           bitmap = new RGBPixel[width * height];
       else {
           width = 1;
           height = 1;
           bitmap = new RGBPixel[width * height];
       }
    }
    
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Grazie per le risposte date fino ad ora
    Ho provato il codice, l'ho riprovato in altri modi analoghi ma niente, forse il problema è il discorso dell'immagine 1x1?
    oppure potrebbero esserci altro errore nel codice
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Difficile dare una risposta se non si conosce questo fantomatico file di tester o test o quel che è.
    Per quel che posso ancora supporre può darsi (oltre al resto) che al tester non vada a genio la constructor initializer list
    
    BitmapImage::BitmapImage(int w, int h) : width(w), height(h) // questa
    
    ma richieda uno specifico assegnamento dentro il costruttore.
    A ogni modo il costruttore che ti ho postato è corretto.
    Per quanto riguarda l'immagine 1 x 1 è perfettamente legale creare un array (o matrice) di dimensione unitaria.
    Per la getPixel() invece cosa non ti torna?
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Sulla funzione get non ero sicurissimo andasse bene ma ragionandoci l'ho capita, per quanto riguarda il costruttore ho fatto un mini test di prova mettendo un main che prova a istanziare vari vettori bitmap e a contare con sizeof il numero di elementi degli array, ma sembra non tornare

    nel .cpp
    BitmapImage::BitmapImage(int w, int h) {
    	// TODO check that w and h are >0. Minimum image size is 1x1
        if (w  > 0 && h > 0) {
            width = w;
            height = h;
        }else{
            width = 1;
            height = 1;
        }
        std::cout<< "" << width << endl;
        std::cout << ""<< height<<endl;
            bitmap = new RGBPixel[width*height];
        std::cout << "Length of array = " << (sizeof(bitmap)/sizeof(*bitmap)) << std::endl;
    }
    nel main()
    #include "BitmapImage.h"
    #include "RGBPixel.h"
    
    
    int main() {
        BitmapImage *b1 = new BitmapImage(-1,-4);
        BitmapImage *b2 = new BitmapImage(6,5);
        BitmapImage *b3 = new BitmapImage(3,2);
        BitmapImage *b4 = new BitmapImage(8,-1);
        BitmapImage *b5 = new BitmapImage(80,3);
        return 0;
    }
    
    la risposta del compilatore è:


    1
    1
    Length of array = 2
    6
    5
    Length of array = 2
    3
    2
    Length of array = 2
    1
    1
    Length of array = 2
    80
    3
    Length of array = 2

    Process finished with exit code 0


    si vede che i valori di width e height sono a 1 ma la lunghezza dell'array non dovrebbe essere diversa?
    forse sto sbagliando tutto, ma dovrebbe venire il prodotto, quindi 1,30,6,1,240
    grazie ancora delle risposte e del tempo che mi hai dedicato
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Questa riga non vale per array allocati dinamicamente:
    
    std::cout << "Length of array = " << (sizeof(bitmap)/sizeof(*bitmap)) << std::endl;
    
    ma vale solo con array statici:
    
    RGBPixel boh[16];
    etc...
    
    il motivo è che bitmap è un puntatore la cui dimensione è fissa e vale 4 o 8 a seconda se stai compilando per 32bit o 64bit.
    Questo comporta che il numero di elementi dell'array è qualcosa di cui devi tenere traccia tu. Sempre.
    Non puoi più ricavarla se la perdi.
  • Re: Dubbi su costruttori copia e operatori di assegnazione

    Ok, perfetto grazie mille per tutti i chiarimenti, molto gentile
Devi accedere o registrarti per scrivere nel forum
12 risposte