Ce que j'essaie de faire est de changer une variable de de classe A code> intérieure de classe B code> et de le rendre identique dans classe C code> class A
{
protected:
string name = "A";
};
class B: public A
{
protected:
string A::name="B";
};
class C: public B
{
// here i want "name" to be "B"
};
3 Réponses :
Ce que vous voulez, c'est d'initialiser la valeur de votre variable dans le constructeur
Donc, il n'y a aucun moyen que je puisse le faire sans constructeurs?
@ BARTASUS1 oui il y a. Voir ma réponse.
Vous ne pouvez pas le faire comme ça. Si le champ est initialisé dans la classe de base, il est initialisé uniquement dans la classe de base. Dans d'autres classes, vous ne pouvez modifier que le champ déjà initialisé. L'un des moyens de faire ce que vous voulez passer la valeur dans le constructeur. Donc:
class A
{
public:
A(std::string initName = "A") : name(std::move(initName)) {}
protected:
string name;
};
class B: public A
{
public:
B() : A("B") {}
};
class C: public B
{
// name will be "B" here
};
Savait de traiter avec elle par des constructeurs, mais j'avais espéré que je peux en faire une manière différente. Quoi qu'il en soit, merci d'aide
@ BARTASUS1 Malheureusement, il n'y a aucun moyen de le gérer sans constructeurs. La raison en est que dans l'initialisation C ++ des champs de la classe de base ne peut se produire que dans la classe de base.
Fait la même chose, mais juste d'un peu différent différent. Peut-être que quelqu'un trouvera plus facilement de lire: b () {A :: nom = "b";} code>
@ BARTASUS1 Non, c'est inefficace et tous ceux qui ont été programmés C ++ pendant un certain temps le changera immédiatement. Vous ne pouvez même pas faire cela pour les classes qui ne peuvent pas être construites par défaut.
@Tedlyngmo Eh bien, pour mon projet, il fait assez bien le travail, alors je vais le laisser
@ BARTASUS1 Vous allez ensuite initialiser nom code> avec une seule valeur, puis écrasez-le directement. C'est un code comme celui-là veut généralement éviter. Si vous ne voulez pas a code> pour avoir un constructeur, pourquoi ne pas donner un accès complet à A code>, comme dans struct a {nom de chaîne = "A"; }; code> Vous pouvez ensuite l'initialiser à partir de B code> comme ceci: Classe B: Public A {Public: B (): A {"B"} {}}; code>.
@Tedlycmo Ces classes A, B, C sont des cours simplifiés de mon projet. Classe A CODE> est "MÈRE", La classe B CODE> est l'une des classes "fractions", et classe C code> représente certains caractères. Je veux que ces personnages contiennent le nom de la fraction qu'ils appartiennent. Je l'ai déjà fait, juste en ajoutant a :: nom = "b"; code> à la classe B code> constructeur
@ BARTASUS1 Je ne dis pas que cela ne fonctionne pas. C'est juste que c'est inefficace et que les programmeurs expérimentés C ++ ne le feraient pas comme ça. Utilisez-vous le polymorphisme? Toutes les instances de A code>, b code> et c code> ont un nom statique? Si tel est le cas, créez simplement une fonction de membre virtuel dans la classe de base que vous pouvez remplacer: virtual const std STD :: string & nom () const {statique const std STD :: string rv = "A"; retour de camping; } code> de cette façon, toutes les instances de A code> partageront la même mémoire pour le nom et la construction d'un A code> ne instancaire pas d'un nouveau std :: string < / code> à chaque fois.
@ BARTASUS1 IN B code> Vous avez simplement Remplacement code> La fonction: const std :: string & nom () const remplacer {statique const std STD :: string rv = "B"; retour de camping; } code> et si C code> est censé avoir le même nom que B code>, ne remplacez pas la fonction dans C code>.
@ BARTASUS1 Il est devenu si moche dans les commentaires, donc j'ai fait une réponse à la place.
@Tedlyngmo pourquoi est-ce inefficace? Ceci est juste une ligne de code ajouté à un constructeur
@ BARTASUS1 parce que vous construisez d'abord la chaîne d'abord, puis Copiez-la une valeur à la fois la copie la construction directement. C'est une différence mineure mais les détails de la matière parfois - et certains objets ne peuvent même pas être construits par défaut, il est donc préférable de " le droit i>" toujours. En outre, si toutes les instances d'une classe partagent le même nom ce que vous faites maintenant sera beaucoup i> plus inefficace que ma version proposée renvoie une chaîne statique. Cette chaîne ne sera instanciée que une fois i> peu importe le nombre de A code> que vous créez. Une fois pour tous les A code> 'A et une fois pour tous les B code> s et C code>'s.
@ BARTASUS1 BTW, j'ai regardé vos autres questions et il semble que vous créez une sorte de jeu, correct? Je suppose que vous utilisez le polymorphisme afin de magasiner misc. Objets / monstres / joueurs déjà, les frais généraux de l'expédition dynamique que je suggère dans ma réponse est (très probablement) dans votre code déjà (ou devrait probablement être).
@Tedlyngmo Oui, vous êtes correct. Je crée un jeu et j'utilise le polymorphisme, mais pour certaines actions différentes. Je suis un peu trop paresseux pour écrire tout ce code, juste pour changer une variable. Oh, A code> a un objet et il y a quelques B code> et de nombreux objets c code> aussi.
@ BartaSus1 "< Je suis un peu trop paresseux i>" - cela reviendra et vous mordera - Promis :-) Quoi qu'il en soit, si vous voulez une réflexion (noms de classes dans l'exécution et la décision de la décision en fonction de la décision) Je pense que vous devriez étudier c ++ 20. La rumeur a-t-elle que la réflexion est ajoutée à la langue. Si tel est le cas, la construction d'un nouveau jeu en 2020 avec une réflexion faite maison le rend vieux avant que cela soit même fini. Pourquoi l'aversion contre les constructions, etc.? Ils font I> vous donnent le contrôle.
" constructions i>" devrait être constructeurs i>. - Écrire sur un téléphone ...
@ BARTASUS1 Avez-vous trouvé un moyen de le faire sans constructeurs ou initialiseurs de toutes sortes?
@TedlyngMo WDYM?
@ BARTASUS1 Je veux dire, puisque vous n'avez accepté aucune des réponses données, avez-vous trouvé une solution alternative?
@Tedlylyngmo j'ai collé de mon choix. Il fait le travail et je ne suis pas particulièrement intéressé à rendre mon jeu aussi efficace que possible. Au moins pour l'instant
Si les noms des classes sont statiques et que vous ne vous dérange pas d'utiliser le polymorphisme, vous pouvez ajouter une fonction de membre Exemple: p> sortie p> virtuel code> renvoyer le nom de la classe. Simplement remplacer code> la fonction dans les classes dérivées pour renvoyer un nom différent.
Voulez-vous changer
nom code> de la classe A de classe B?Non Non, je veux juste changer de variable déclarée dans
Classe A CODE>, INTÉRIEURClasse B CODE> et faire cette évaluation variable dans le formulaire modifié à l'intérieurClasse C CODE> @ Tonytannous