[C++]Freundschaft für einzelnes Member

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Hi,

Ich zermartere mir gerade das Hirn, wie man ein bestimmtes Member einer Klasse für eine bestimmte andere Klasse / Funktion sichtbar macht …

private, protected und public funktionieren jeweils für ganze Sammlungen von Membern und machen diese für eine ganze Sammlung von anderen Objekten sichtbar.

friend ist schon spezieller, es macht Member nur für ein einziges anderes Objekt sichtbar. Aber es macht eben alle Member sichtbar, nicht nur das eine, das man braucht. (Und es hat ein paar Probleme mit Templates.)

Was ich brauche, ist eine Freundschaft für ein einzelnes Member. Leider kann ich das bisher nur über sehr hässliche Tricks realisieren …

… gibt es dafür eine saubere Lösung? („sauber“: ohne virtuelle Funktionen und ähnlichen Overhead, schließlich ist das ein Compile-Time-Problem.)

Gruß, Ky

Edit: Achja, in meinem Fall soll eine bestimmte Klasse nur von einer bestimmten Funktion ausgespuckt werden können (K’tor nur von jener Funktion aus abrufbar). Vielleicht hilft das. Hier ist meine bisherige Lösung:

Code: Alles auswählen

class Producer;	// Produzent mit alleinigem Recht für die Herstellung des …
class Product;	// … Produkts.

namespace {
	// Alles, was nur …
	class Product_ForProducer {
	friend class Producer; // … für den Produzent sichtbar ist, …
	private: // … und für niemand sonst – wie …
		// … ein Konstruktor für ein Produkt.
		static Product NamedConstructor();
	};
}

// Das Produkt.
class Product
	: public Product_ForProducer 	// Damit wird "NamedConstructor()" in diese Klasse übernommen, da Freundschaft zwar
					// nicht vererbt werden kann, aber bei Vererbung für die Basisklasse erhalten bleibt.
{
private:
	// Damit erhält der nur für den Produzenten sichtbare Teil der Klasse Zugriff auf den Konstruktor, und niemand sonst.
	friend Product_ForProducer;
	Product() { }
public:
	// Zeug, das das Produkt kann. U.a. auch, dass es …
	~Product() { } // … aufgebraucht wird.
};

// Kann nicht in "Product_ForProducer" definiert werden, da "Product" dort noch nicht definiert ist.
Product Product_ForProducer::NamedConstructor() {
	return Product();
}

class Producer {
public:
	static Product Produce() {
		return Product::NamedConstructor();
	}
};
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 583
Registriert: 05.07.2003, 11:17

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Lord Delvin »

Krishty hat geschrieben:..., schließlich ist das ein Compile-Time-Problem.
So wie ich dich verstehe ist das eben kein Compile-Time Problem, da es zur Compilezeit eben noch keine Objekte gibt. Was spricht gegen Constproxys? Und warum haben überhaupt Objekte die dein Objekt nich verändern dürfen einen Zeiger auf das Objekt?
Also ich glaub du willst die Klasse komplett private machen mit einem friend const proxy, der das dann regelt und einem friend Producer, der das objekt Produziert und einen const proxy erzeugt.

Gruß
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Lord Delvin hat geschrieben:So wie ich dich verstehe ist das eben kein Compile-Time Problem, da es zur Compilezeit eben noch keine Objekte gibt.
Natürlich ist es das, denn auf welches Member wann zugegriffen werden kann ist rein von der Deklaration abhängig.
Lord Delvin hat geschrieben:Und warum haben überhaupt Objekte die dein Objekt nich verändern dürfen einen Zeiger auf das Objekt?
Es geht nicht darum, was verändert werden darf, sondern welche Member(funktionen) wann überhaupt für wen sichtbar sind.
Lord Delvin hat geschrieben:Was spricht gegen Constproxys?
Nichts, solange ich nicht weiß, was das ist ;) Ist das Pattern irgendwo erklärt, oder hat es noch einen anderen Namen? Die Google-Ergebnisse sind ziemlich dünn. Edit: Achso, klar, Proxy für const. Ja, ich schaue mal, ob ich das sauber hinkriege.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Stefan Zerbst »

Hi,

auch wenn ich friends nicht leiden kann: Bevor man da viel drumherum konstruiert sollte man Producer eine Methode spendieren welche ein Product intern für die Producer Instanz konstruiert. Und genau diese eine Methode kann man dann als friend setzen:

Code: Alles auswählen

class Producer
{
public:
	static Product Produce() { return new Product(); }
};

class Product
{
friend Producer::Produce;

private:
	Product() { }

public:
	~Product() { }
};
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Wie gesagt macht friend alles verfügbar. Das reicht also nicht aus, weil Producer nicht nur Zugriff auf den Konstruktor enthält, sondern auch auf alles andere, was an Product privat bleiben sollte.

Allerdings gehe ich momentan zu einer Lösung mit Schnittstellen (eine für den Produzenten, eine für den Verbraucher, etc) über, die alle von der Basisklasse erben und keinen Konstruktor haben. Erzeugt werden können sie dann nur per static_cast der Basisklasse.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Stefan Zerbst »

Hm ... wie gesagt: friend an sich ist schon eklig. Aber eine Klasse zu haben die nur exakt auf eine einzige Methode einer anderen Klasse benutzen darf ist noch ekliger. Da muss man anfangen sich zu fragen, ob man da nicht Design um des Designs Willen reinzuprügeln versucht. Macht es denn überhaupt Sinn dem Producer alles andere zu verbieten?

Davon abgesehen hat nur die Producer::Produce Methode Zugriff auf alles im Product. Von daher würde ich noch mal ganz deutlich die Frage stellen wo du da konkrete Probleme siehst. Wenn sich jemand illegal Zugriff verschaffen will dann kann er das auch so. Und die oben gezeigte Methode deutet dem Anwender deiner Bibliotheken ganz klar an, was erwünscht ist. :)

Ciao,
Stefan
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Stefan Zerbst hat geschrieben:Hm ... wie gesagt: friend an sich ist schon eklig. Aber eine Klasse zu haben die nur exakt auf eine einzige Methode einer anderen Klasse benutzen darf ist noch ekliger. Da muss man anfangen sich zu fragen, ob man da nicht Design um des Designs Willen reinzuprügeln versucht. Macht es denn überhaupt Sinn dem Producer alles andere zu verbieten?
Zuerst einmal verbietet man ihm nicht mehr als jeder anderen Klasse auch, man erlaubt nur zusätzlich den Konstruktor. Es kann schon sinnvoll sein, wenn man kontrollierte Instanzen braucht – wenn das Produkt z.B. ein Schlüssel mit trivialem Konstruktor ist, und man nicht einfach „Schlüssel(0)“ schreiben und sonstwas übergeben können soll.
Stefan Zerbst hat geschrieben:Davon abgesehen hat nur die Producer::Produce Methode Zugriff auf alles im Product.
Wie gesagt, nur auf das, was in Product public und in Product_ForProducer deklariert ist. Zugriff auf alles haben in letzter Konsequenz nur Member-Funktionen, wie es sein sollte.
Stefan Zerbst hat geschrieben:Und die oben gezeigte Methode deutet dem Anwender deiner Bibliotheken ganz klar an, was erwünscht ist. :)
Nur, wenn der Anwender meiner Bibliothek nicht auch noch den Produzenten implementieren können soll. Dann bleibt das Produkt nämlich die einzige Klasse, über die ich das Design noch steuern kann.

Ich versuche wirklich gerade, das anderweitig zu lösen oder ganz zu entfernen … es kann ja nur falsch sein, wenn es sich nicht einfach umsetzen lässt. Aber mir funken auch gerade ein paar unverwandte Bugs dazwischen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2119
Registriert: 25.02.2009, 13:37

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Alexander Kornrumpf »

Bin nicht sicher ob ich jetzt alles richtig gelesen/verstanden habe.

Unter C# habe ich es so gelöst:

Klingt erstmal nicht hilfreich, aaaber:

Das Produkt ist eine private innere Klasse des Builders (!=Producer?!). Somit kann nur der Producer Objekte dieser Klasse anlegen bzw. auf deren public Schnittstelle zugreifen.

Hier das aaaber:
Die innere Klasse implementiert ein Interface (public teil des Produkts ohne Konstruktor) und der Producer gibt nach außen diese Schnittstelle zurück. Bzw. eine "Instanz" des Interface, wenn man das so nennt. Damit können alle externen arbeiten.

Ergebnis sollte klar sein und ungefähr das was du vor hast (bis auf Missverständnisse).

Diskussion (diese Punkte kann ich für C++ nicht abschließend beurteilen):

"Nachteil" ist das nur eine Klasse diese Art von "besonderem Freund" sein kann.

Ich habe neulich auf Wikipedia im Zuge unseres Sprachenvergleichs nachgelesen dass C++ innere Klassen kennt, habe diese in meiner C++ Zeit jedoch nie verwendet.

Wenn der C++ Kompiler sich "logisch" verhält dürfte ein dynamic_cast von dem Interface (abstrakte Klasse in C++) auf die eigentliche Klasse nur innerhalb der äußeren Klasse gehen. Wenn es sowas wie protected innere Klassen gibt, können auch abgeleitete Producer das Produkt herstellen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Ziemlich genau das versuchte ich gestern zu machen :)

Das Problem ist nur folgendes: Sobald es eine innere Klasse protected ist (ja, läuft wie du es vermutest, habe es bis jetzt immer zwecks Verständlichkeit des Problems ignoriert), kann nurnoch die Containerklasse diese Klasse anlegen. Kein Problem soweit. Ist jedoch die Schnittstelle, die das Produkt implementiert, eine Subklasse des Produkts, ist auch diese von außen nicht erreichbar – das bedeutet, ich kann sie außerhalb des Produzenten niemals instantiieren, sogar dann nicht, wenn der Produzent eine solche Klasse als Rückgabewert zurückgibt.

Was mir gerade für eine Idee kommt: Man könnte dem Produzenten zwei Subklassen geben – Produkt und Rohstoff – wobei erstere die Schnittstelle ist, die du angesprochen hast, und zwar öffentlich. Letztere ist geschützt und kann daher nur im Produzenten instantiiert werden. Öffentliches Produkt erbt von geschütztem Rohstoff und verlangt eine Instanz des Rohstoffs, die man ja nur zur Verfügung stellen kann, wenn man der Produzent (oder eine erbende Klasse) ist. So kann nur der Produzent ein Produkt erzeugen, aber außen kann man es immernoch per Copy-Konstruktor speichern.

Das müsste gut klappen und ich bin wirklich heiß, das zu implementieren … aber ich schreibe bis Freitag Klausuren, kann also noch dauern, bis ich dazu komme :/

Achja, ob man von außen zu geschützten Klassen casten kann, kann ich momentan garnicht sagen. Ist eine interessante Frage, da ein Cast auch nur ein Template ist und das bedeuten würde, dass sich Templates nicht auf private Subklassen instantiieren ließen – was garnicht so sinnlos wäre, wie es sich anhört.

Achja, woran ich gearbeitet hatte war, dass das Produkt keinen Konstruktor hat, also überhaupt nicht instantiiert werden kann und dass ich stattdessen den Rohstoff – da identisch mit dem Produkt – zu selbigem hochcaste. Klingt aber an sich schon sehr evil.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2119
Registriert: 25.02.2009, 13:37

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Alexander Kornrumpf »

Ist jedoch die Schnittstelle, die das Produkt implementiert, eine Subklasse des Produkts, ist auch diese von außen nicht erreichbar – das bedeutet, ich kann sie außerhalb des Produzenten niemals instantiieren, sogar dann nicht, wenn der Produzent eine solche Klasse als Rückgabewert zurückgibt.
Ja das ist schon klar. Allerdings ist mir nicht klar, wieso die Schnittstelle überhaupt Subklasse von Produkt sein soll. Der Ausdruck Schnittstelle ist leider mehrfach besetzt, einmal im Sinne von "public-Interface" und einmal im Sinne von "C#/Java-Interface-Keyword". Egal in welcher Bedeutung, die Schnittstelle mit der Externe arbeiten sollen muss logischerweise öffentlich sein, deswegen spricht wohl nichts da gegen eine ganz normale "toplevel" (abstrakte) Klasse daraus zu machen von der die innere Klasse dann erbt. Was mir dabei auffällt: kann eine Klasse überhaupt von einer eigenen inneren Klasse erben?

Irgendwie ist entweder dein Problem komplizierter als meins oder deine Lösung (oder beides).

P.S. Du verwendest den Begriff "Subklasse" für mich impliziert der eine Vererbungsbeziehung, und ist nicht gleichbedeutend mit einer inneren Klasse.

P.P.S.

Vielleicht hätte ich direkt Code hinschreiben sollen:

Code: Alles auswählen

public interface IProduct
{
    //Was die ganze Welt vom Produkt sehen darf
}

public class Builder
{
    protected class Produkt : IProduct
    {
        //Was hier public ist aber nicht in IProduct können nur Builder und dessen nachkommen sehen
    }
   public IProduct buildProduct
   {
        Product product = new Product();
        //Irgendwas spannendes um den Builder zu rechtfertigen
        return product; //Ab hier ist es nur noch ein IProduct    
   }
}

Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Chromanoid »

Also in Java würde ich die fraglichen Klassen in ein Paket tun und die fraglichen Funktionen protected machen. Dann könnten nur die Klassen im selben Paket und erbende Klassen das ganze benutzen. Geht das in C++ vielleicht ähnlich mit namespaces und einem anderen spezifizierer? Schließlich musst du den Zugriff auf die Funktion ja nur nach außen hin schützen. Innerhalb der Bibliothek, weisst du ja was du tust...
Alexander Kornrumpf
Moderator
Beiträge: 2119
Registriert: 25.02.2009, 13:37

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Alexander Kornrumpf »

Chromanoid hat geschrieben: Innerhalb der Bibliothek, weisst du ja was du tust...
lol :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Alexander Kornrumpf hat geschrieben:Ja das ist schon klar. Allerdings ist mir nicht klar, wieso die Schnittstelle überhaupt Subklasse von Produkt sein soll.
Wie du schon gesagt hast, ist „implementieren“ doppelt besetzt – ich hatte es so verstanden, dass die Klasse die Schnittstelle umschließen soll.
Alexander Kornrumpf hat geschrieben:Was mir dabei auffällt: kann eine Klasse überhaupt von einer eigenen inneren Klasse erben?
Nein, denn die Superklasse muss beim Erben bereits definiert sein.
Alexander Kornrumpf hat geschrieben:P.S. Du verwendest den Begriff "Subklasse" für mich impliziert der eine Vererbungsbeziehung, und ist nicht gleichbedeutend mit einer inneren Klasse.
Selbstverständlich nicht. Müdigkeit :)
Alexander Kornrumpf hat geschrieben:P.P.S. Vielleicht hätte ich direkt Code hinschreiben sollen:
Der sieht tatsächlich schon um einiges einfacher aus … werde ich mir anschauen.
Chromanoid hat geschrieben:Geht das in C++ vielleicht ähnlich mit namespaces und einem anderen spezifizierer?
Man kann Klassen durch anonyme Namespaces innerhalb einer Datei behalten – aber eben nur innerhalb einer Datei, das ist in diesem Fall zuwenig.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Brainsmith
Establishment
Beiträge: 109
Registriert: 04.09.2009, 13:52
Echter Name: Fabbo

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Brainsmith »

Also.. Ich hab da ne Idee..
Du könntest innerhalb deiner Oberklasse ein privates Objekt erstellen, dass ausschließlich dafür da ist, in den Konstruktor von Product zu gesteckt zu werden.
Der triviale Konstruktor bleibt private und du macht einen neuen, wo das private Object reinkommt.
Und den neuen Konstruktor von Product versiehst du ganz einfach mit dem präfix "explicit". Schon kann nurnoch deine Klasse das Ding aufrufen.

=D Ist natürlich nicht so der Bringer, da dadurch Overhead entsteht, aber ne Möglichkeit wärs.. ^^
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Bei der Thread-Pfrickelei gestern hatte ich dieses verdammte Problem schon wieder: Eine Schnittstelle, die einen kleinen Datensatz verwaltet, der von zwei Seiten bearbeitet wird. Diese beiden Seiten greifen auf die Schnittstelle völlig unterschiedlich zu – und es wäre katastrophal, wenn eine Seite die Funktionen nutzen würde, die für die andere Seite bestimmt sind.

Das Beispiel vom Anfang dieses Threads ist ziemlich verwirrend und ich hoffe, dieses hier ist klarer:

Wir haben eine Schnittstelle zwischen dem Programm und einem Arbeits-Thread. Sie verwaltet alle mit dem Thread verbundenen Daten (das Thread-Handle, den Ausführungsstatus etc).
Sie ist für den Erzeuger des Threads die einzige Verbindung zu diesem und bietet mindestens den Konstruktor und den Destruktor, damit er Arbeiter-Threads erzeugen und zerstören kann. Und dann noch Funktionen, um Aufgaben aufzutragen.
Weiterhin ist sie für den Arbeiter-Thread selber die einzige Verbindung zum auftraggebenden Thread und bietet ihm Funktionen, mit denen er seine Aufgaben abholen und die Ergebnisse einreichen kann.
Die Schnittstelle sieht also für die eine Seite anders aus als für die andere. Und könnte die eine Seite auf die Funktionalität der anderen zugreifen, wäre das katastrophal – dann könnte der Arbeiter auf sich selber warten, oder sich selber zerstören, oder der Auftraggeber seine eigenen Aufgaben abholen.

Die einfachste Lösung ist, beide seiten der Schnittstelle abstrakt zu definieren und dann eine Klasse zu schreiben, die beide implementiert:

Code: Alles auswählen

// Sicht des Auftraggebers auf den Arbeiter
class IWorkerThread {
public:
    virtual void addTask(…) = 0;
};

// Sicht des Arbeiters auf den Auftraggeber
class ISupervisor {
public:
    virtual bool hasNewTask(…) = 0;
};

class CThreadController
    : public IWorkerThread // der Benutzer dieser Klasse ist der Auftraggeber
    , protected ISupervisor // diese interne Schnittstelle geht nur an den Arbeits-Thread raus
{
private:
    static void thread(ISupervisor & supervisor); // Hauptschleife
protected:
    HANDLE myThread;
public:

    CThreadController()
        : IWorkerThread()
        , ISupervisor()
        , myThread(createThread(thread, static_cast<ISupervisor &>(*this)))
    { }

    void addTask(…) override;
    bool hasNewTask(…) override;

};
Das hat nur leider den Nachteil, dass jeder Aufruf virtual wird. Angesichts der Tatsache, dass alle Datentypen schon zur Kompilierzeit feststehen, ziemliche Verschwendung.

Das kann mit mit virtueller Vererbung in den Griff bekommen: Man definiert die Basisfunktionalität in einer Basisklasse, erbt die beiden Seiten der Schnittstelle virtual davon und vereinigt sie wieder in einer finalen Klasse. Damit lassen sich alle Schnittstellen nicht-virtual und trotzdem getrennt halten – die Unkosten reduzieren sich auf leere Virtual Function Tables am Anfang der Klassen.

Eine Lösung ganz ohne Unkosten wären Concepts. Damit ließe sich für jede Seite der Schnittstelle ein Konzept definieren; alle Funktionen, die die Schnittstelle nutzen, würden zu Templates gemacht, die das Konzept erwarten. Aber auch damit hätte man noch mindestens einen Vererbungsschritt und ein paar using-Direktiven drin.

Nur so meine Gedanken zu der Sache.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: [C++]Freundschaft für einzelnes Member

Beitrag von kaiserludi »

Ich greife das Thema mal auf für ein ähnliches Problem.
In C# gibt es ja das Schlüsselwort Internal, um etwas innerhalb einer Bibliothek public zu machen, aber nicht außerhalb.
Kann man das irgendwie in C++ simulieren?

Bisher habe ich mir geholfen, in dem Klassen innerhalb der Bibliothek, die Zugriff auf bestimmte Member brauchen anderer Klassen der Bibliothek brauchen, friends sind, so dass ich keinen public-Zugriff auf diese Member für Klassen außerhalb der Lib geben muss.
Dummerweise hebt das natürlich das Geheimnisprinzip innerhalb der Lib komplett auf, weil ich nichts mehr wirklich praivate machen kann, was somit auch für diese Firends nicht zugreifbar bleibt.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Freundschaft für einzelnes Member

Beitrag von Krishty »

Ja, das wäre auch wieder so ein Fall von selektiver Freundschaft. Ich versuche schon die ganze Zeit, einen Fehler in meinem Konzept zu finden, um es eleganter hinzukriegen – es scheint mir aber mehr und mehr eine C++’ Konzept der Objektorientierung innewohnende Schwäche zu sein. Bei den meisten anderen Sprachen stellt sich das Problem überhaupt nicht, weil dort schlicht und einfach jeder Aufruf virtuell ist und es dashalb keine Rolle spielt, dass man jede Facette durch eine Schnittstelle aussiebt. Vielleicht ist der Fehler auch meine typische C++-Denkweise – „Wenn es schon zur Kompilierzeit eindeutig ist, darf es nicht erst zur Laufzeit aufgelöst werden.“
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++]Freundschaft für einzelnes Member

Beitrag von BeRsErKeR »

Was spricht denn gegen folgendes?

Code: Alles auswählen

class MyClass
{
    friend class Producer;
public:
    MyClass(void) : myMembers() { }
    ~MyClass(void);

private:
    MyClass(const MyClass &other);
    const MyClass & operator=(const MyClass &other);

    class Members
    {
        friend class MyClass;
    private:
        Members(void) { /* initialize members */ }
        void SomeMethod(void);
        int SomeMemberVar;
    };

    Members myMembers;
};
Producer kann nur den Ctor aufrufen. Copy-Ctor und Assign-Operator sind nicht definiert. Er kommt zwar an myMembers ran, kann damit aber nichts machen (also keine Änderungen vornehmen), da alle Methoden, Member und auch der Ctor nur für MyClass sichtbar sind.
Ohne Input kein Output.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: [C++]Freundschaft für einzelnes Member

Beitrag von kaiserludi »

BeRsErKeR hat geschrieben:Was spricht denn gegen folgendes?

Code: Alles auswählen

class MyClass
{
    friend class Producer;
public:
    MyClass(void) : myMembers() { }
    ~MyClass(void);

private:
    MyClass(const MyClass &other);
    const MyClass & operator=(const MyClass &other);

    class Members
    {
        friend class MyClass;
    private:
        Members(void) { /* initialize members */ }
        void SomeMethod(void);
        int SomeMemberVar;
    };

    Members myMembers;
};
Producer kann nur den Ctor aufrufen. Copy-Ctor und Assign-Operator sind nicht definiert. Er kommt zwar an myMembers ran, kann damit aber nichts machen (also keine Änderungen vornehmen), da alle Methoden, Member und auch der Ctor nur für MyClass sichtbar sind.
Sorry, sehe deine Antwort jetzt erst.
Ja, der Ansatz sieht in der Tat sehr vielversprechend aus. Werde damit mal ein wenig rumspielen.
Danke.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Antworten