Problème avec pointeurs private dans une classe

Résolu
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011 - 27 déc. 2011 à 01:36
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011 - 27 déc. 2011 à 23:10
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

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 10:30
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
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 10:33
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
3
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011
27 déc. 2011 à 11:30
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
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 11:44
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
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 11:44
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
3
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
27 déc. 2011 à 11:45
Sans vouloir être expéditif, peux-tu lancer ton debugger pour nous donner la ligne qui génère l'erreur ?
3
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011
27 déc. 2011 à 12:57
3
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011
27 déc. 2011 à 15:23
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)
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 15:38
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
3
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011
27 déc. 2011 à 23:10
C'est bon je m'en suis sorti avec les resize, ça marche !

Merci à tous de votre aide, et en particulier à CptPingu !
3
vvdbvivien07 Messages postés 9 Date d'inscription mercredi 7 décembre 2011 Statut Membre Dernière intervention 27 décembre 2011
27 déc. 2011 à 13:09
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 ?
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 déc. 2011 à 13:37
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
0
Rejoignez-nous