Problème avec pointeurs private dans une classe [Résolu]

Signaler
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011
-
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011
-
Bonjour,
Je suis en train de réaliser un traitement d'image en c++ et voici mon problème:

L'utilisateur doit rentrer le nom d'un fichier pgm et le programme se charge de le lire et récupère les valeurs de Hauteur et Largeur de l'image.
Dans mon .h , j'ai une classe image dans laquelle j'ai deux pointeurs private (*p_hauteur et *p_largeur) car je souhaiterais que mon tableau puisse changer de hauteur et de largeur. Cependant, lors de la compilation j'ai le message d'erreur :
error: invalid use of non-static data member 'Image::p_hauteur'|
error: from this location|
error: array bound is not an integer constant|
error: invalid use of non-static data member 'Image::p_largeur'|
error: from this location|
error: array bound is not an integer constant|
||Build finished: 6 errors, 0 warnings|


Voici le .h :
#ifndef DEF_IMAGE
#define DEF_IMAGE

#include <string>
#include   // std::cin, std::cout, std::endl
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <map>
#include <ctime>

class Image
{

    private:

    double *p_hauteur;
    double *p_largeur;

    public:

    std::string nom_image;
    std::string ident;
    std::string image_sauvegardee;
    std::string action;
    char unoctet;

    int m_i, m_j, m_pixel_maxi;


    double getHauteur();
    double getLargeur();

    double tabPix[p_hauteur.getHauteur()][p_largeur.getLargeur()];


 

};


#endif



et une partie du .cpp :
#include "Image.h"
using namespace std;


//Constructeurs

Image::Image() : p_hauteur, p_largeur
{
    p_hauteur = new double();
    p_largeur = new double();
}

double Image::getHauteur()
{
    return *p_hauteur;
}


double Image::getLargeur()
{
    return *p_largeur;
}


Merci d'avance pour votre aide

12 réponses

Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Bonjour.

Ton constructeur possède des champs invalides:

Image::Image() : p_hauteur, p_largeur

Devrait être:
Image::Image() : p_hauteur(0), p_largeur(0)



________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Quelques conseils:
- Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- Préfère les conteneurs de la STL (std::vector, std::list, etc...) plutôt que d'utiliser des tableaux fait "à la main".
- Extension C++: .hpp/.cpp/.hxx ou .hh/.cc/.hxx, le .h étant pour du C.
- hauteur et largeur n'ont pas besoin d'être des pointeurs... (Inutile de toute façon si tu utilises un std::vector).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011

Merci de vos précieux conseils ! je n'ai plus de problème de compilation !

Cependant, dans la console, dès que je rentre le nom de mon image storm.pgm , j'ai la fenêtre :" projet.exe a cessé de fonctionner " ,et je ne comprends pas pk? Je n'ai même pas le message dans la console qui devrait s'afficher avec le cout "Image chargée"

Je vous remets le header modifié:

#ifndef DEF_IMAGE
#define DEF_IMAGE

#include <string>
#include   // std::cin, std::cout, std::endl
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <map>
#include <ctime>
#include <vector>

class Image
{

public:

        std::string nom_image;
        std::string ident;
        std::string image_sauvegardee;
        std::string action;

        std::vector<std::vector<double> > tabPix;

        char unoctet;

        double m_i, m_j, m_hauteur, m_largeur, m_pixel_maxi;


        void chargement();
      
      

};


#endif



et mon .cpp :

#include "Image.h"
using namespace std;



///////////////////////////////////////////////////////////////////////////////
////////////////////////////// Chargement /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

// Fonction qui permet de charger/lire l'image initiale

void Image::chargement()
{
    //char unoctet;
    cout << "\nEntrez le nom de l'image" << endl; // l'image storm est P2
    cin >> nom_image;

    // voir le mode HEX des visionneuse
    ifstream  fin (nom_image.c_str());
    fin >> ident;

    if (ident == "P5")
    {
        cout << "\ntype d&#8217;image non trait\202e" <<endl ;
        return ; // modifier selon le type
    }

    fin.get(unoctet);

    fin >> m_largeur >> m_hauteur;
    fin >> m_pixel_maxi;

    for (m_i = 0; m_i<m_hauteur ; m_i++)
    {
        for (m_j = 0; m_j<m_largeur; m_j++)
        {
            fin >> tabPix[m_i][m_j];
        }
    }

    cout<<"Image charg\202e"<<endl;
    
}


Merci d'avance
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
La taille du tableau est certe dynamique, mais il faut tout de même lui donner une taille !
Donc soit tu fais des ".push_back()" (taille automatique quand tu insères), soit tu fais des "resize()" à la taille voulue, et tu mets des valeurs aux champs (comme tu le fais).
Actuellement ton tableau dynamique à une taille de 0,0 donc forcément...

(PS: Évite vraiment les using namespace).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Pense à lire la documentation:
http://www.cplusplus.com/reference/stl/vector/

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

Sans vouloir être expéditif, peux-tu lancer ton debugger pour nous donner la ligne qui génère l'erreur ?
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011

Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011

Je n'arrive toujours pas à changer ce code :

  for (m_i = 0; m_i<m_hauteur ; m_i++)
    {
        for (m_j = 0; m_j<m_largeur; m_j++)
        {
            fin >> tabPix[m_i][m_j];
        }
    }


en remplaçant avec des pushback et mon vector deux dimensions

std::vector<std::vector<double> > tabPix;


Comment faire ? (Même en lisant la doc, je ne comprends pas car la doc ne parle du pushback pour un vector une dim)
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Deux exemples d'utilisation d'un std::vector simple.
// 5 6 7

Avec push_back:
std::vector<double> tab;

tab.push_back(5);
tab.push_back(6);
tab.push_back(7);


Avec resize:
std::vector<double> tab;
tab.resize(3);

tab[0] = 5;
tab[1] = 6;
tab[2] = 7;


Exemple avec tableau double dimension.
// 5 6 7
// 8 9 4

Avec push_back:
std::vector<std::vector<double> > matrix;
std::vector<double> tab;
tab.push_back(5);
tab.push_back(6);
tab.push_back(7);


matrix.push_back(tab);
tab.clear(); // Vide le tableau

tab.push_back(8);
tab.push_back(9);
tab.push_back(4);
matrix.push_back(tab);


Avec resize:
std::vector<std::vector<double> > matrix;
matrix.resize(2);
matrix[0].resize(3);
matrix[1].resize(3);

matrix[0][0] = 5;
matrix[0][1] = 6;
matrix[0][2] = 7;

matrix[1][0] = 8;
matrix[1][1] = 9;
matrix[1][2] = 4;


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011

C'est bon je m'en suis sorti avec les resize, ça marche !

Merci à tous de votre aide, et en particulier à CptPingu !
Messages postés
9
Date d'inscription
mercredi 7 décembre 2011
Statut
Membre
Dernière intervention
27 décembre 2011

Pour CptPingu :

Pourquoi le SDZ nous recommande ceci pour les namespace :

Dans les .h, il est recommandé de ne jamais mettre la directive using namespace std; car cela pourrait avoir des effets néfastes lorsque vous utiliserez la classe par la suite.
Par conséquent, il faut rajouter le préfixe "std::" devant chaque string du .h. Sinon, le compilateur vous sortira une erreur du type "string does not name a type".


http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html

c'est pour cela que j'avais placé le namespace dans le .cpp

Donc selon toi, je n'ai pas besoin du tout de using namespace std ?
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Sur l'image, tu vois bien que ça merde au niveau de operator[] en gros quand tu essaies d'accéder un élément du tableau.
Tu peux en déduire qu'il y a une tentative d'accès hors borne. Comme ton tableau à une taille de 0, c'est normal :).
cf mes posts précédents pour résoudre le souci.

Donc selon toi, je n'ai pas besoin du tout de using namespace std ?

Oui, il y a d'autre moyen plus sécurisé que le "using namespace".
Lis ceci: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question