web-dev-qa-db-fra.com

Comment déclarer un tableau avec une classe personnalisée?

J'essaie de déclarer un tableau avec une classe personnalisée. Lorsque j'ai ajouté un constructeur à la classe, mon compilateur se plaint qu'il n'y a "aucun constructeur correspondant pour l'initialisation du nom [3]".

Voici mon programme:

#include <iostream>

using namespace std;

class name {
  public:
    string first;
    string last;

  name(string a, string b){
    first = a;
    last = b;
  }
};

int main (int argc, const char * argv[])
{

  const int howManyNames = 3;

  name someName[howManyNames];

  return 0;
}

Que puis-je faire pour faire cette course et que fais-je de mal?

13
Moshe

Vous devez fournir un constructeur par défaut. Pendant que vous y êtes, corrigez également votre autre constructeur:

class Name
{
public:
  Name() { }
  Name(string const & f, string const & l) : first(f), last(l) { }
  //...
};

Alternativement, vous devez fournir les initialiseurs:

Name arr[3] { { "John", "Doe" }, { "Jane", "Smith" }, { "", "" } };

Ce dernier est conceptuellement préférable, car il n'y a aucune raison que votre classe devrait ait une notion d'état "par défaut". Dans ce cas, il vous suffit de avoir pour fournir un initialiseur approprié pour chaque élément du tableau.

Les objets en C++ ne peuvent jamais être dans un état mal défini; si vous y réfléchissez, tout devrait devenir très clair.


Une alternative consiste à utiliser un conteneur dynamic, bien que ce soit différent de ce que vous avez demandé:

std::vector<Name> arr;
arr.reserve(3);  // morally "an uninitialized array", though it really isn't

arr.emplace_back("John", "Doe");
arr.emplace_back("Jane", "Smith");
arr.emplace_back("", "");

std::vector<Name> brr { { "ab", "cd" }, { "de", "fg" } }; // yet another way
22
Kerrek SB

Pour initialiser par défaut un tableau de Ts, T doit être constructible par défaut. Normalement, le compilateur vous donne gratuitement un constructeur par défaut. Cependant, puisque vous avez déclaré vous-même un constructeur, le compilateur ne génère pas de constructeur par défaut.

Vos options:

  • ajouter un constructeur par défaut au nom, si cela a du sens (je ne pense pas, mais je ne connais pas le domaine du problème);
  • initialiser tous les éléments du tableau lors de la déclaration (vous pouvez le faire car name est un agrégat);

      name someName[4] = { { "Arthur", "Dent" },
                           { "Ford", "Prefect" },
                           { "Tricia", "McMillan" },
                           { "Zaphod", "Beeblebrox" }
                         };
    
  • utiliser un std::vector à la place, et n'ajoutez d'élément que lorsque vous les avez construits.

5

Vous avez besoin d'un constructeur sans paramètre pour pouvoir créer une instance de votre classe. Votre constructeur actuel nécessite deux paramètres de chaîne d'entrée.

Normalement, C++ implique d'avoir un tel constructeur (= constructeur sans paramètre par défaut) s'il n'y a aucun autre constructeur déclaré. En déclarant votre premier constructeur avec deux paramètres, vous écrasez ce comportement par défaut et vous devez maintenant déclarer ce constructeur explicitement.

Voici le code de travail:

#include <iostream> 
#include <string>  // <-- you need this if you want to use string type

using namespace std; 

class name { 
  public: 
    string first; 
    string last; 

  name(string a, string b){ 
    first = a; 
    last = b; 

  }

  name ()  // <-- this is your explicit parameterless constructor
  {}

}; 

int main (int argc, const char * argv[]) 
{ 

  const int howManyNames = 3; 

  name someName[howManyNames]; 

  return 0; 
}

(BTW, vous devez inclure pour rendre le code compilable.)

Une autre méthode consiste à initialiser explicitement vos instances lors de la déclaration

  name someName[howManyNames] = { {"Ivan", "The Terrible"}, {"Catherine", "The Great"} };
2
Alexander Galkin

il vous suffit d'ajouter un constructeur par défaut à votre classe pour ressembler à ceci:

class name {
  public:
    string first;
    string last;

  name() {
  }

  name(string a, string b){
    first = a;
    last = b;
  }
};
2
Kamyar Souri

Ta classe:

class name {
  public:
    string first;
    string last;

  name() { }  //Default constructor.

  name(string a, string b){
    first = a;
    last = b;
  }
};

A un constructeur explicite qui nécessite deux paramètres de chaîne. Les classes sans constructeur écrit explicitement obtiennent des constructeurs par défaut ne prenant aucun paramètre. L'ajout de celui explicite a empêché le compilateur de générer ce constructeur par défaut pour vous.

Donc, si vous souhaitez créer un tableau d'objets non initialisés, ajoutez un constructeur par défaut à votre classe pour que le compilateur sache comment les créer sans fournir ces deux paramètres de chaîne - voir la ligne commentée ci-dessus.

2