2017-09-03 2 views
0

Ich habe zwei Klassen, A und B. Klasse A ist eine Transformation (eine Matrix), die eine Transformation für einen gegebenen Vektor durchführt.Initialisierung einer optionalen konstanten Referenz in einer Klasse

class A{ 
public: 
    ... 
    A(...){}; 
    ... 
    void func_A(std::vector<double>& vec){ 
     /* Transform vector vec */ 
    } 
}; 

Klasse B hat zwei Mitglieder; std::vector<double> &vec eine Referenz eines Vektors, und const std::vector<std::shared_ptr<A> > &a_ptrs eine konstante Referenz eines anderen Vektors mit geteilten Zeigern der Klasse A, die verschiedene Transformationen darstellen. a_ptrs kann null, eine oder mehrere Transformationen enthalten. Eine der Aufgaben der Klasse B besteht darin, diese (falls vorhanden) Transformationen auf den Vektor vec anzuwenden.

class B{ 
public: 
    std::vector<double> &vec; 
    const std::vector<std::shared_ptr<A> > &a_ptrs; 

    B(std::vector<double> &vec_ref) : vec(vec_ref){ 
    /* How to initialize a_ptrs if there are no transformations available? 
     That is, there are no shared pointers of class A available.*/ 
    }   

    B(std::vector<double> &vec_ref, 
     const std::shared_ptr<A> &aptr) : vec(vec_ref){ 
     /* How to initialize a_ptrs if there is only one transformation available, and 
     I just decide to pass a const reference to the shared pointer of A? */ 
    } 

    // No issues with this constructor: 
    B(std::vector<double> & vec_ref, 
     const std::vector<std::shared_ptr<A> > &aptr) : vec(vec_ref), a_ptrs(aptr){} 

    void func_B(){ 
     ... 
     // Apply the transforms: 
     for(int i=0; i<a_ptrs.size(); ++i){ 
      a_ptrs[i]->func_A(vec); 
     } 
     .... 
    } 
}; 

Zu diesem Zweck ist, wie Sie sehen können, habe ich den Konstruktor der Klasse B überlastet Wenn const std::vector<std::shared_ptr<A> > &a_ptrs als Argument an den Konstruktor von B übergeben wird, ist alles in Ordnung. Aber mein Problem ist, dass ich einfach nicht weiß, wie ich diese konstante Referenz für die Fälle initialisiere, in denen null oder nur eine Transformation verfügbar ist, d. H. a_ptrs ist leer oder hat nur ein Element.

Wenn a_ptrs nur ein Element hat, möchte ich in der Lage sein, einfach eine const std::shared_ptr<A> &aptr zu übergeben, und initialisiert a_ptrs irgendwie darauf basierend.

Ich möchte auch keine Kopien des gemeinsamen Zeigers auf Klasse A in Klasse B machen. Ich möchte auch einen konstanten Verweis auf den gemeinsamen Zeiger haben.

Basierend auf dem, was ich im Internet gefunden habe, gibt es eine Möglichkeit, boost::optional oder std::experimental::optional zu verwenden, aber ich konnte es nicht funktionieren lassen.

Ich bin ziemlich neu in C++, und ich habe an diesem Problem für zwei Tage ohne Glück gearbeitet. Wie kann ich dieses Problem überwinden? Sollte ich eine andere Designstrategie haben? Ich würde mich über Kommentare oder Vorschläge freuen, die mir helfen, dieses Problem zu lösen.

+1

Sie machen dies zu kompliziert. Erstens sollte "B :: vec" ein Argument für "B :: func_B" sein (Konsistenz mit "A"). Dann kann "a_ptrs" keine Referenz sein, und Sie haben einige "const" Qualifier in Funktionsparameter-Typen fehlen. – LogicStuff

+0

Warum haben Sie Referenzmitglieder? –

+0

@LogicStuff, ja, du hast Recht, 'B :: vec' sollte ein Argument für' B :: func_B' sein. Warum kann ich 'a_ptrs' nicht als Referenz verwenden? Was ist die Alternative? Ich versuche, keine Kopien von 'Klasse A' zu haben. – Pafnuty

Antwort

0

Referenzen müssen initialisiert werden, keine Ausnahmen.

jedoch in Ihrer Situation, können Sie dieses Problem umgehen, indem Sie eine leere Vektor zur Hand, diese Fälle zu behandeln:

class B { 
    static const std::vector<std::shared_ptr<A> > empty_a; 

    std::vector<double> &vec; 
    const std::vector<std::shared_ptr<A> > &a_ptrs; 
public: 

    B(std::vector<double> &vec_ref) 
    : vec(vec_ref), 
     a_ptrs(empty_a) {} 
}; 
+0

Danke, @Frank, für diesen Vorschlag. Was ist mit dem zweiten Konstruktor? – Pafnuty

Verwandte Themen