Comment écrire une fonction get pour un tableau de caractères privé dans la classe à la fois en .h et .cpp? Je ne sais pas si je devrais utiliser char * pour le type à la place ou autre chose.
J'ai essayé d'utiliser char [] getCharArray ();
mais cela ne semble pas acceptable.
// in .h class Foo{ private: char charArray[32]; public: char getCharArray(); // How to write the get function? }; // in .cpp char Foo::getCharArray(){ // How to write the get function in .cpp? }
4 Réponses :
Utilisez un std :: array
et renvoyez-lui une référence const
. Cela fournit un accès direct en lecture seule:
void printFoo(const Foo& foo) { printf("%s", foo.getCharArray().data()); }
Si le code a besoin d'un pointeur const char *
vers le tableau, utilisez le data ()
fonction membre de std::array
:
#include <array> class Foo { public: const std::array<char, 32>& getCharArray() const { return charArray; } private: std::array<char, 32> charArray{}; // The '{}' zero-initializes the array. };
renvoyer une référence de l'état interne de l'objet n'est pas une bonne pratique.
@Hoodi C'est une référence const
. Il ne peut pas être modifié par accident.
Ouais, mais ce n'est pas non plus recommandé. Lisez le livre de Scott Mayer, i.e. Effective C ++ (item # 28)
@Hoodi Aucune des choses mentionnées ici ne semble s'appliquer ici. " l'appelant peut en fait modifier les points renvoyés par ces poignées. " Ce n'est pas le cas ici, puisque nous retournons une référence const
. " si vous renvoyez un pointeur interne à l'appelant, il peut survivre à la vie de votre objet, et le pointeur deviendra un pointeur pendant ". Ce n'est pas non plus le cas ici, car nous ne renvoyons pas de pointeur. En dehors de cela, il n'y a rien dans la question OPs qui nous permet de dire si l'exposition de charArray
est recommandée ou non. Nous ne savons pas vraiment ce que Foo
est censé être.
Voici l'extrait du livre: "C'est pourquoi toute fonction qui renvoie un handle vers une partie interne de l'objet est dangereuse. Peu importe que le handle soit un pointeur, une référence ou un itérateur. Ce n'est pas le cas. Peu importe si elle est qualifiée avec const. Peu importe que la fonction membre renvoyant le handle soit elle-même const. Tout ce qui compte, c'est qu'un handle soit renvoyé, car une fois que cela est fait, vous courez le risque que le handle survivra l'objet auquel il se réfère. "
En termes simples, si vous stockez la référence retournée quelque part et que l'objet d'origine sort du champ d'application, vous serez confronté à une référence pendante, ce qui n'est pas bon.
@Hoodi Le stockage d'une référence est une opération explicite. Cela ne peut pas arriver par accident.
La réponse précédente n'ayant pas répondu à la question…
class Foo{ private: char charArray[32]; public: const char* getCharArray() const { return charArray; } };
Pour votre question telle que posée
// in .h #include <array> // C++11 and later class Foo { private: std::array<char, 32> charArray; public: std::array<char, 32> getCharArray() const; }; // in .cpp // include the header! std::array<char, 3> Foo::getCharArray() const { return charArray; }
Gardez à l'esprit que ce qui précède renvoie un pointeur vers des données privées de la classe Foo
(plutôt qu'une copie du tableau ). Les qualificatifs const
empêchent l'appelant d'utiliser (délibérément ou accidentellement) le pointeur renvoyé pour manipuler les données privées de la classe Foo
.
Cependant, votre approche ( l'utilisation d'un tableau brut de char
dans une classe) est considérée comme une mauvaise approche en C ++. Il a également tendance à être plus difficile à utiliser.
Une meilleure approche serait d'utiliser un conteneur standard plutôt qu'un tableau brut.
// in .h class Foo { private: char charArray[32]; public: const char *getCharArray() const; }; // in .cpp // include the header! const char *Foo::getCharArray() const { return charArray; }
Dans cette approche , l'appelant de Foo :: getCharArray ()
reçoit une COPY du tableau entier, plutôt qu'un pointeur ou une référence à des données privées de la classe Foo
. L'appelant peut mettre à jour en toute sécurité le tableau qu'il reçoit, puis le remettre ultérieurement à la classe Foo
(par exemple via un setter). Alors que, avec l'utilisation d'un pointeur et d'un tableau brut, plus de gymnastique est nécessaire pour obtenir un effet similaire.
Facultativement, une référence const
au std :: array
peut être renvoyé dans ce qui précède, ce qui peut éviter une copie inutile d'objets complets.
Une chose que vous pouvez faire que personne n'a mentionnée est de renvoyer une référence au tableau de caractères bruts sans avoir besoin de std :: array
. J'ai volé cette idée à https://stackoverflow.com/a/34439639/10290252 .
//.h file class Foo{ private: char charArray[32]; public: char (&getCharArray())[32]; }; // .cpp file char (&Foo::getCharArray())[32]{ return charArray; }
Obtenez quelques bons livres à lire. Ils devraient vous dire tout ce que vous devez savoir et plus encore.
Voulez-vous que la fonction getter renvoie une copie du tableau ou lui fournisse un accès direct? En cas d'accès direct, voulez-vous que cet accès soit en lecture seule ou en lecture-écriture? De plus, est-ce supposé être une chaîne ou est-ce censé être un tableau de 32 valeurs d'octets?
@NikosC. Je veux que la fonction get renvoie un tableau de caractères, car j'inclurai également une fonction set dans la classe, je veux que l'accès soit en lecture seule.
@NikosC. Il est supposé être un tableau de caractères avec des valeurs de 32 octets. Je préfère utiliser une chaîne parce que c'est plus facile et plus familier pour moi, mais un tableau de caractères est requis ici.
Vous ne pouvez pas renvoyer un tableau brut en C ++. envisagez d'utiliser
std :: array
oustd :: vector
.