Si j'ai une classe Rectangle
class Rectangle{
private:
double width;
double height;
public:
void Set(double w , double l){
width = w;
height = l;
}
};
et je décleare un objet tel:
Rectangle *Obj;
puis essayez d'initialiser ses propriétés:
Obj->Set(3,5);
le compilateur affiche au moment de l'exécution: The variable 'Obj' is being used without being initialized.
Le problème peut être résolu par:
Rectangle *Obj=new Rectangle;
Je demanderais la raison! Et pourquoi le compilateur n'affiche aucune erreur au moment de la compilation?
Rectangle *Obj;
définit juste un pointeur vers un objet de classe Rectangle
. La définition d'un pointeur ne réserve aucune mémoire pour l'objet lui-même, juste pour le pointeur . Ainsi, si vous accédez au pointeur, vous vous retrouverez probablement à une adresse en mémoire qui n'appartient même pas à votre processus. Cependant, le compilateur ne peut pas savoir que vous n'avez pas initialisé le pointeur (le mot clé ici est aliasing) et ne peut donc pas générer de message d'erreur.
La solution utilise soit new
comme vous l'avez suggéré, soit déclare une instance de Rectangle
comme ceci:
Rectangle Obj;
qui appellera un constructeur par défaut. Vous pouvez ensuite définir vos membres en utilisant
Obj.Set(3, 5);
et je décleare un objet tel:
Rectangle *Obj;
Mal, cela déclare un pointeur, pas un objet. Les pointeurs doivent être initialisés en utilisant new
ou en leur affectant l'adresse d'un objet existant.
Mmm un peu de confusion là-bas:
le compilateur affiche au moment de l'exécution: la variable 'Obj' est utilisée sans être initialisée
C'est ce que vous appelleriez temps de compilation. Simplement redresser le jargon.
De plus, le moyen le plus simple serait de
Rectangle Obj;
Obj.Set(3,5);
ce qui est suffisant pour la plupart des scénarios, à l'exception des allocations dynamiques ou des conteneurs polymorphes:
std::vector<Shape*> v;
v.Push_back(new Rectange());
v.back()->Set(3,5);
v.Push_back(new Circle());
v.back()->Set(3,5);
//
Bien que chaque fois que vous utilisez new
, vous devez également vous souvenir de delete
. Cela peut être tout à fait un cauchemar (à la lumière d'exceptions aussi). Je suggère:
std::vector<std::shared_ptr<Shape*> > v;
v.Push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);
v.Push_back(std::make_shared<Circle>());
v.back()->Set(3,5);
pointer without new déclare quelque chose sans mémoire .. SO u doit utiliser new avec pointer. Cependant Rectangle rect; allouera par défaut la mémoire.
pour vérifier cela, faites un constructeur dans la classe Rectangle comme,
void Rectangle
{
cout<<"Rectangle Constructor";
}
puis, en principal
Rectangle *rect; -->>O/P -- "Nothing"
Rectangle rect2; -->>O/P -- Rectangle Constructor
rect=new Rectangle; -->>O/P -- Rectangle Constructor
Avec Rectangle *Obj;
, vous déclarez un pointeur sur un rectangle, mais vous n'avez pas dit à Obj
vers quel rectangle il doit pointer. Vous pouvez définir ou instancier Obj
ultérieurement sur un Rectangle
existant ou uniquement si vous en avez besoin.
C++ vise à vous donner un contrôle précis sur votre mémoire et vos performances. En fait, c'est pourquoi il est utilisé dans certains environnements embarqués! L'instanciation automatique de Obj
pose plusieurs "problèmes"
Obj
?Obj
?Rectangle
sur le tas?Obj
, puis instanciez-la au moment de l'exécution à l'aide d'une méthode complexe que nous ne pouvons pas analyser statiquement?Ce que vous faites n'est pas une erreur de syntaxe, c'est ce sur quoi les compilateurs jettent des erreurs - des erreurs lors de la compilation. Un analyseur (l'un est intégré à Visual Studio 2010 Professional) peut vous avertir que vous utilisez une variable non initialisée, bien que cela soit facultatif et que vous deviez l'activer.
pourquoi le compilateur n'affiche aucune erreur au moment de la compilation?
Parce que c'est syntaxiquement correct. Cependant, de telles instructions conduiront à comportement indéfini, les compilateurs intelligents émettront toujours un avertissement.
Dans g ++, vous pouvez transformer ce type d'avertissement du compilateur en erreurs.