2014-01-15 5 views
5

Ich schreibe eine Matrix-Klasse für die CUDA-Verarbeitung.Warnung: Basisklasse sollte im Kopierkonstruktor explizit initialisiert werden

Ich habe eine Vektorklasse (fortan als Elements bekannt) geschrieben und diese für die Matrixbasis verwendet. Hier

ist die Template-Definition:

template <typename T, std::size_t M, std::size_t N> 
class Matrix : public Elements< Elements< T, N >, M > { 

} 

Es sollte beachtet werden, dass nichts dynamisch in der Elements Klasse zugeordnet ist, noch in der Matrix Klasse.

Ich bekomme eine warning: base class ‘struct Elements<Elements<double, 2ul>, 2ul>’ should be explicitly initialized in the copy constructor Warnung im Kopierkonstruktor. Hier ist der Kopierkonstruktor:

DEVICE HOST 
    Matrix(const Matrix & that) { 
     for (std::size_t ind = 0; ind < M; ind++) { 
      for (std::size_t jnd = 0; jnd < N; jnd++) { 
       (*this)[ind][jnd] = that[ind][jnd]; 
      } 
     } 
    } 

Was mache ich falsch?

+0

möglich Duplikat [Warnung: Basisklasse ‚A‘ explizit im Copykonstruktor initialisiert werden soll] (http://stackoverflow.com/questions/9098979/warning-base-class-a-should-be-explicitly-initialized-in-the-copy-constructor) – starsplusplus

Antwort

4

Sie initialisieren die Basisklasse im Kopierkonstruktor nicht. Versuchen Sie folgendes:

Matrix(const Matrix & that) : Elements<Elements<T, N>, M>(that) { 
    /* ... */ 
} 

Die Initialisiererliste der abgeleiteten Klasse Copy-Konstruktor einen expliziten Aufruf der Basisklasse enthalten soll Konstruktor kopieren, genau wie bei allen anderen Konstrukteuren, andernfalls wird die Basisklasse sein default-initialisiert .

Edit: Es kann nützlich sein, eine private Definition

typedef Elements<Elements<T, N>, M> basetype; 

in Ihrer Klasse irgendwo zu haben.

+0

@dyp: Vielen Dank für die Entdeckung, dass - die Antwort entsprechend aktualisiert. – arne

+0

Es wäre flexibler, die Vorlagenargumente beim Aufrufen des Konstruktors von Element zu verwenden, oder dies könnte nur kompiliert werden, wenn eine Matrix mit einem Doppeltyp verwendet wird. – Kindread

+0

Genau das habe ich gesucht. Ich bearbeite Ihre Antwort, um 'typename T' anstelle von double, explizit zu verwenden. Ansonsten, gute Show. –

0

Wenn Sie explizit einen Kopierkonstruktor einer abgeleiteten Klasse definieren und nicht den Kopierkonstruktor der Basisklasse in der ctor-Liste aufrufen, ruft der Compiler selbst den Standardkonstruktor für die Basisklasse auf. Es ist möglich, dass es nicht das ist, was Sie wollten. Der Compiler warnt dich also.

Ich habe ein Beispiel, das den Unterschied in meinem artical
"Implicitly defined copy constructor and explicitly defined copy constructor: what is the difference" es zeigt, ist in russischer Sprache geschrieben, aber Sie werden es lesen zum Beispiel Google-Dienst übersetzen mit der Lage.

0

Für jede abgeleitete Klasse muss die Basisklasse erstellt werden, wann immer die abgeleitete Klasse ist. Wenn Ihre Basisklasse keinen Standardkonstruktor (0-Argument) hat, müssen Sie angeben, wie Sie sie in allen Konstruktoren Ihrer abgeleiteten Klasse erstellen.

Also, vorausgesetzt Elemente eine öffentliche Kopie Konstruktor haben, müssen Sie so etwas wie:

Matrix(const Matrix & that) 
: Elements<Elements<T, N>, M>(that) 
{ 
    ... 
}