1

Je voudrais accéder à un membre protégé d'un objet de type A depuis un objet dérivant de A.
En gros, faire ça :
class A
{
protected:
	int m;
};

class B : public A
{
	void f()
	{
		A a;
		B b;
		m = 0;	 // ok (même objet)
		b.m = 0; // ok (objet du même type)
		// mais c'est ça que je veux faire :
		a.m = 0; // échec (objet du type de base) : « 'A::m' : cannot access protected member declared in class 'A' »
	}
};

Les renseignements que j'ai trouvé à propos des membres public, protected et private parlent toujours d'accès depuis les fonctions membres de la classe, mais ne précisent jamais comment ça se passe entre différentes instances. On dirait que ça se passe mal justement.
Alors est ce qu'il y a un moyen pour que je puisse accéder à un membre de A depuis n'importe quel objet dérivé de A ? (sans rendre ce membre public si possible, ni déclarer explicitement la classe B friend de la classe A, car A ne devrait pas avoir connaissance de B)
avatar

2

la solution qui consisterait à utiliser "friend" ne te conviendrait pas ? (c'est pas super joli, mais bon :/)

[edit] je ne sais pas lire, c'est écrit noir sur blanc que c'est pas ce que tu veux grin
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

enfin je veux bien dire que A est pote avec toutes ses classes dérivées (pasque A est sympa), mais pas juste B ^^
avatar

4

uep je vois le problème, mais à part des trucs immondes style "((B*)&a)->m = 0;", je ne connais pas de solution ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

Par contre, à propos de ce hack, si je caste en B* un objet qui est en fait de type C, lui aussi dérivé de A, est ce que ça pourrait planter ? Je dirais que non, puisque je n'accède qu'à la partie définie dans la classe A, mais j'en suis pas sûr.
avatar

6

bonne question, à partir du moment où tu touches quelque chose qui est contenu dans A, je suppose que quelle que soit la classe dérivée à laquelle appartient la variable que tu utilises il n'y a pas de problème, mais ça reste à confirmer ^^

(enfin le contraire me semblerait étonnant, et engendrerait surtout un beau bordel)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

7

Ça doit dépendre de l'organisation en mémoire des membres des classes. Si le compilo met en premier les membres du type de base, puis chacun des types dérivés, ça doit aller (et c'est ce qu'il fait je suppose). Par contre en cas d'héritage multiple, là, ça doit moins bien se passer grin
avatar

8

uep, en tout cas g++ a l'air de toujours procéder de cette façon; après je sais pas si c'est juste son comportement ou si c'est écrit dans une quelconque norme ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

reinterpret_cast<B*>(static_cast<A*>(a)).m est plus sûr (pour l'héritage multiple justement). Et avec g++, il faudra probablement compiler avec -fno-strict-aliasing (ou déclarer B avec __attribute__((may_alias))) aussi, d'autres compilateurs pourraient aussi nécessiter quelque chose du même type.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

10

tu veux dire *reinterpret_cast<B*>(static_cast<A*>(&a)).m ? mais dans ce cas, à quoi sert le static_cast<A*> puisque &a est déjà de type A* ?

Enfin merci à tous les deux, au moins ça marche smile
avatar

11

Le static_cast est redondant effectivement, il sera déjà effectué quand tu affectes l'objet à ton A*.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

12

J'ai du mal à comprendre les réponses des autres parce que je suis un peu fatigué, mais quand je me suis retrouvé confronté au problème initial, ma solution a été d'ajouter une méthode statique protégée à A, pour que B puisse l'utiliser.
class A
{
public:
	A(int toto) : m_toto(toto) { }

	void Afficher() const
	{
		std::cout << "Coucou! " << m_toto << std::endl;
	}
protected:
	int m_toto;
	static int GetTotoOf(A const &a);
};

int A::GetTotoOf(A const &a)
{
	return a.m_toto;
}

class B : public A
{
public:
	int FonctionQuiABesoinDUnAutreA(A const &a) const;
};

int B::FonctionQuiABesoinDUnAutreA(A const &a) const
{
	return GetTotoOf(a) + m_toto;
}
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

13

Effectivement, ça m'a l'air beaucoup plus propre que le hack qu'on avait proposé.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité