 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
lionel letoffet Guest
|
Posted: Tue Mar 08, 2005 7:21 am Post subject: Problème d'opérateur [] |
|
|
Bonjour, voici quelques lignes extraites de mon code qui me posent problème
à l'éxecution .
// Headers
------------
class Point
{
public :
float x,y;
Point(const Point& Pt){x=Pt.x; y=Pt.y;}
Point(float valx = 0.0,float valy = 0.0){x = valx;y = valy;}
};
/ ArrayPoint
//**************************************************************************
***
class ArrayPoint : public CObject
{
protected:
float *m_X;
float *m_Y;
unsigned int m_Count;
public:
Point operator[](int nIndex) ;
virtual Point GetAt(unsigned int);
ArrayPoint(unsigned int Count,float valx, float valy);
virtual ~ArrayPoint();
};
// ArrayPoint.cpp : fichier d'implémentation
//
#include "stdafx.h"
#include "ArrayPoint.h"
ArrayPoint::ArrayPoint(unsigned int Count,float Inc)
{
m_Count=0;
m_X=NULL;
m_Y=NULL;
if(Count>0){
m_X=new float[Count];
m_Y=new float[Count];
for (int i=0;i
m_Count=Count;
}
}
//**************************************************************************
***
ArrayPoint::~ArrayPoint()
{
if(m_X)delete[]m_X;
if(m_Y)delete[]m_Y;
}
//**************************************************************************
***
Point ArrayPoint::operator [](int Index )
{
Point pt(m_X[Index],m_Y[Index]);
return pt;
}
Tout ceci ce compile sans problème. Le souci est à l'éxecution quand dans
une application je tente d'utiliser l'opérateur []
ArrayPoint *m_Array1;
m_Array1=new ArrayPoint(1024*1024,1,1);
Point pt1;
pt1 = m_Array1[3];
Je ne peux pas compiler cette dernière ligne!!!
J'obtiens toujours l'erreur suivante :
error C2679: binary '=' : no operator found which takes a right-hand operand
of type 'ArrayPoint' (or there is no acceptable conversion)
Avez vous une idée ou une piste ???
Je suis en visual studio .NET.
Merci d'avance .
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Mar 08, 2005 8:03 am Post subject: Re: Problème d'opérateur [] |
|
|
lionel letoffet wrote:
| Quote: | // Headers
------------
class Point
{
public :
float x,y;
Point(const Point& Pt){x=Pt.x; y=Pt.y;}
Point(float valx = 0.0,float valy = 0.0){x = valx;y = valy;}
};
/ ArrayPoint
//**************************************************************************
***
class ArrayPoint : public CObject
|
Est-ce qu'il y a une raison pour l'héritage de CObject ? J'ai
l'impression que ta classe a la sémantique d'une collection, et
en général (mais il y a des exceptions), les collections en C++
n'héritent de rien.
protected ? Et il y a des données qui suivent ? Je me serais
attendu à private.
| Quote: | float *m_X;
float *m_Y;
|
Et pourquoi pas simplement Point* ?
| Quote: | unsigned int m_Count;
public:
Point operator[](int nIndex) ;
|
Habituellement, il y a deux operator[], l'un const, et l'autre
non. S'il y en a un qui renvoie un objet (et non une référence),
c'est celui qui est const.
| Quote: | virtual Point GetAt(unsigned int);
|
Pourquoi virtuel ? Quelle est la différence entre l'operator[]
et la fonction GetAt ? Pourquoi est-ce que l'un prend un int, et
l'autre un unsigned ? Pourquoi est-ce que l'un est virtuel, et
l'autre non ?
| Quote: | ArrayPoint(unsigned int Count,float valx, float valy);
virtual ~ArrayPoint();
};
// ArrayPoint.cpp : fichier d'implémentation
//
#include "stdafx.h"
#include "ArrayPoint.h"
ArrayPoint::ArrayPoint(unsigned int Count,float Inc)
{
m_Count=0;
m_X=NULL;
m_Y=NULL;
if(Count>0){
m_X=new float[Count];
m_Y=new float[Count];
for (int i=0;i<Count;i++){m_X[i]=(i*Inc);m_Y[i]=(i*Inc);}
m_Count=Count;
}
}
|
En général, on préfère les initialisateurs, du genre :
ArrayPoint::ArrayPoint(
unsigned count,
float increment )
: m_X( count > 0 ? new float[ count ] : NULL )
, m_Y( count > 0 ? new float[ count ] : NULL )
, m_count( count )
{
for ( unsigned i = 0 ; i < m_count ; ++ i ) {
m_X[ i ] = i * increment ;
m_Y[ i ] = i * increment ;
}
}
Mais ça ne fait que réprendre ta logique ; il reste plusieurs
problèmes ?
-- D'abord, pourquoi traiter count == 0 à part. On a
parfaitement droit à faire un new de 0 octets, pourvu qu'on
ne déréférence jamais le pointeur qu'il renvoie.
-- Mais surtout, évidemment, le code est incorrect. C'est assez
difficile à écrire un constructeur qui fait deux allocations
sans l'utilisation des pointeurs intelligents -- à ta place,
par exemple, des boost::scoped_array ferait bien l'affaire ;
un seul new Point[ count ] me semble encore beaucoup mieux,
et un std::vector< Point > idéal (en supposant que le but de
la manip est autre que d'apprendre comment écrire des
collections, évidemment).
Si c'était moi, je n'aurais qu'une seule variable membre :
std::vector< Point > m_data ;
et le constructeur serait simplement :
ArrayPoint::ArrayPoint(
unsigned count,
float increment )
{
m_data.reserve( count ) ;
for ( unsigned i = 0 ; i < count ; ++ i ) {
m_data.push_back( Point( i * increment, i * increment ) ) ;
}
}
| Quote: |
//**************************************************************************
***
ArrayPoint::~ArrayPoint()
{
if(m_X)delete[]m_X;
if(m_Y)delete[]m_Y;
}
|
Les if ne sont pas nécessaire ; delete est bien défini sur un
pointeur nul.
| Quote: |
//**************************************************************************
***
Point ArrayPoint::operator [](int Index )
{
Point pt(m_X[Index],m_Y[Index]);
return pt;
}
|
Et comment tu utilises l'opérateur sur la côté gauche d'une
affectation ? J'aurais vu plutôt deux opérateurs :
Point // ou : Point const&
ArrayPoint::operator[](
unsigned index ) const
{
assert( index < m_data.size() ) ;
return m_data[ index ] ;
}
Point&
ArrayPoint::operator[](
unsigned index )
{
assert( index < m_data.size() ) ;
return m_data[ index ] ;
}
| Quote: | Tout ceci ce compile sans problème. Le souci est à l'éxecution
quand dans une application je tente d'utiliser l'opérateur []
ArrayPoint *m_Array1;
m_Array1=new ArrayPoint(1024*1024,1,1);
|
Pourquoi le pointeur et l'allocation ? Pourquoi simplement :
ArrayPoint array( 1024*1024, 1, 1 ) ;
| Quote: | Point pt1;
pt1 = m_Array1[3];
Je ne peux pas compiler cette dernière ligne!!!
|
Évidemment, puisque m_Array est un pointeur, et non un
ArrayPoint. (*m_Array)[ 3 ] ferait l'affaire, mais typiquement,
c'est assez rare d'avoir besoin des pointeurs à des
collections ; les pointeurs servent surtout pour des objets
entités (et évidemment, dans l'implémentation des collections,
et d'autres utilisation de bas niveau).
| Quote: | J'obtiens toujours l'erreur suivante :
error C2679: binary '=' : no operator found which takes a
right-hand operand of type 'ArrayPoint' (or there is no
acceptable conversion)
|
En effet, le message d'erreur pourrait mener à confusion, parce
que pour des raisons histér^H^Horique, les pointeurs en C++
acceptent les opérateurs [] aussi -- ce que tu as écrit, c'est
l'équivalent de *(m_Array + 3). Qui serait un ArrayPoint (et non
un Point), sauf que tu n'en as alloué qu'un, et donc, l'objet
n'existe pas.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Ahmed MOHAMED ALI Guest
|
Posted: Tue Mar 08, 2005 1:12 pm Post subject: Re: Problème d'opérateur [] |
|
|
Bonjour,
m_Array1 est un pointeur sur ArrayPoint.Pour accéder à l'opérateur
d'indiçage,il faut le déréférencer afin de récupérer l'objet sur lequel il
pointe.
m_Array1[3] est un pointeur sur le quatrième élément d'un tableau de
ArrayPoint ,pour qui de plus de la mémoire n'est pas allouée.
Pour corriger ton problème:
ArrayPoint m_Array1(1024*1024,1,1);
pt1 = m_Array1[3];
ou bien
ArrayPoint *m_Array1;
m_Array1=new ArrayPoint(1024*1024,1,1);
pt1 = (*m_Array1)[3];
Cordialement,
Ahmed MOHAMED ALI
"lionel letoffet" <letoffet (AT) club-internet (DOT) fr> wrote
| Quote: | Bonjour, voici quelques lignes extraites de mon code qui me posent
problème
à l'éxecution .
// Headers
------------
class Point
{
public :
float x,y;
Point(const Point& Pt){x=Pt.x; y=Pt.y;}
Point(float valx = 0.0,float valy = 0.0){x = valx;y = valy;}
};
/ ArrayPoint
//**************************************************************************
***
class ArrayPoint : public CObject
{
protected:
float *m_X;
float *m_Y;
unsigned int m_Count;
public:
Point operator[](int nIndex) ;
virtual Point GetAt(unsigned int);
ArrayPoint(unsigned int Count,float valx, float valy);
virtual ~ArrayPoint();
};
// ArrayPoint.cpp : fichier d'implémentation
//
#include "stdafx.h"
#include "ArrayPoint.h"
ArrayPoint::ArrayPoint(unsigned int Count,float Inc)
{
m_Count=0;
m_X=NULL;
m_Y=NULL;
if(Count>0){
m_X=new float[Count];
m_Y=new float[Count];
for (int i=0;i
m_Count=Count;
}
}
//**************************************************************************
***
ArrayPoint::~ArrayPoint()
{
if(m_X)delete[]m_X;
if(m_Y)delete[]m_Y;
}
//**************************************************************************
***
Point ArrayPoint::operator [](int Index )
{
Point pt(m_X[Index],m_Y[Index]);
return pt;
}
Tout ceci ce compile sans problème. Le souci est à l'éxecution quand dans
une application je tente d'utiliser l'opérateur []
ArrayPoint *m_Array1;
m_Array1=new ArrayPoint(1024*1024,1,1);
Point pt1;
pt1 = m_Array1[3];
Je ne peux pas compiler cette dernière ligne!!!
J'obtiens toujours l'erreur suivante :
error C2679: binary '=' : no operator found which takes a right-hand
operand
of type 'ArrayPoint' (or there is no acceptable conversion)
Avez vous une idée ou une piste ???
Je suis en visual studio .NET.
Merci d'avance .
|
|
|
| Back to top |
|
 |
lionel letoffet Guest
|
Posted: Mon Mar 14, 2005 9:10 pm Post subject: Re: Problème d'opérateur [] (résolu) |
|
|
OK j'ai compris .
il fallait déréférencer le pointeur !!
Point pt1;
pt1 = *(m_Array1)[3];
"lionel letoffet" <letoffet (AT) club-internet (DOT) fr> a écrit dans le message de
news:422d5308$0$309$7a628cd7 (AT) news (DOT) club-internet.fr...
| Quote: | Bonjour, voici quelques lignes extraites de mon code qui me posent
problème
à l'éxecution .
// Headers
------------
class Point
{
public :
float x,y;
Point(const Point& Pt){x=Pt.x; y=Pt.y;}
Point(float valx = 0.0,float valy = 0.0){x = valx;y = valy;}
};
/ ArrayPoint
//**************************************************************************
***
class ArrayPoint : public CObject
{
protected:
float *m_X;
float *m_Y;
unsigned int m_Count;
public:
Point operator[](int nIndex) ;
virtual Point GetAt(unsigned int);
ArrayPoint(unsigned int Count,float valx, float valy);
virtual ~ArrayPoint();
};
// ArrayPoint.cpp : fichier d'implémentation
//
#include "stdafx.h"
#include "ArrayPoint.h"
ArrayPoint::ArrayPoint(unsigned int Count,float Inc)
{
m_Count=0;
m_X=NULL;
m_Y=NULL;
if(Count>0){
m_X=new float[Count];
m_Y=new float[Count];
for (int i=0;i
m_Count=Count;
}
}
//**************************************************************************
***
ArrayPoint::~ArrayPoint()
{
if(m_X)delete[]m_X;
if(m_Y)delete[]m_Y;
}
//**************************************************************************
***
Point ArrayPoint::operator [](int Index )
{
Point pt(m_X[Index],m_Y[Index]);
return pt;
}
Tout ceci ce compile sans problème. Le souci est à l'éxecution quand dans
une application je tente d'utiliser l'opérateur []
ArrayPoint *m_Array1;
m_Array1=new ArrayPoint(1024*1024,1,1);
Point pt1;
pt1 = m_Array1[3];
Je ne peux pas compiler cette dernière ligne!!!
J'obtiens toujours l'erreur suivante :
error C2679: binary '=' : no operator found which takes a right-hand
operand
of type 'ArrayPoint' (or there is no acceptable conversion)
Avez vous une idée ou une piste ???
Je suis en visual studio .NET.
Merci d'avance .
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|