2016-07-19 11 views
0

Ich habe eine const char Array in Base Klasse.const char Array multiple Initialisierung C++

static const char *_myArray[10]; 

Ich habe ein Kind Child1 Klasse CPP-Datei erstellt und _myArray[10] mit der folgenden Syntax initialisieren.

const char *Base::_myArray[10] = {"red", "green", "blue"}; 

Ich habe ein anderes Kind Namen Child2 und ich brauche dieses Array mit {"pink", "yellow", "brown"} Werte intialize.

Ich versuchte ähnlich in Child2, aber es konnte das Array auf diese Weise nicht initialisieren. Es gibt Kompilierungsfehler, dass ein Problem mit der Mehrfachinitialisierung besteht.

Ich verwende dieses Array von meiner Base-Klassen-Instanz (Casting von abgeleiteten Klasse) und Daten sollten von abgeleiteten Klassen gefüllt werden (da Daten von Kind zu Kind variieren können).

Was ist der richtige Ansatz, um dieses Problem zu lösen? Ihre Unterstützung wird sehr geschätzt.

Vielen Dank im Voraus!

+1

Sie wissen, dass es nicht zwei '_myArray's sein wird? Dies gilt für alle Instanzen aller abgeleiteten Klassen. – LogicStuff

+0

machen Sie es nicht statisch oder verschieben Sie Ihre Array-Deklaration in die Unterklassen. –

+0

was willst du wirklich erreichen? –

Antwort

0

Ihr Problem ist das Schlüsselwort static. Dies bedeutet, dass alle Instanzen dieser Klasse das eine Array gemeinsam haben (und das Array sogar ohne Instanz verfügbar wäre, wenn es als public deklariert würde). Sie initialisieren das Array mit {"red", "green", "blue"}, danach ist eine Änderung nicht mehr möglich, da das Array const ist. Dann versuchen Sie es erneut mit {"pink", "yellow", "brown"} zu initialisieren, was zu dem Fehler führen wird.

Warum muss dieses Array statisch sein? Entfernen Sie die statische und führen Sie die Initialisierung in Ihrer Initialisierungsliste im Konstruktor.

Hier ist die korrekte Syntax für diesen Ansatz:

Base::Base() : _myArray{"red", "green", "blue"} 
{ 
    // Constructor here 
} 

Und was ich auch das Problem festgestellt, dass Sie diese eindimensionale Matrix zweidimensionalen behandeln. Jede Zelle Ihres Arrays kann genau ein Zeichen speichern, keine C-Zeichenfolge. Sie könnten das umgehen, indem Sie zweidimensionale Arrays verwenden oder ein Array von std::strings verwenden.

+0

ich versucht habe zu intialize wie Child1 :: Chiled1: _myArray ({ "rot", "grün", "blau"}) { } Child2: Chiled2: _myArray ({ "Black", "white", "braun"}) { } Aber zeigt Syntext Fehler .. – mirzapinku

+0

die Antwort redigierte die notwendigen Informationen – Nidhoegger

+0

Base enthalten :: Base(): _myArray { "rot", "grün", "blau"} { // Konstruktor hier } das ist in Ordnung für die Basis. aber wenn Sie möchten, das von Kind zu tun, wie Child :: Child(): _myArray { "rot", "grün", "blau"} { // Konstruktor hier } dann entstehen Fehler. – mirzapinku

0

Es gibt einige Möglichkeiten, dieses Problem zu nähern: Eine Möglichkeit besteht darin, explizit statisches Element in der Klasse jedes Mal zu schreiben:

class Base {/*...*/}; 

class InheritedFirst : public Base 
{ 
    static constexpr const char* _myArray[10] = {"First"}; 
}; 

class InheritedSecond : public Base 
{ 
    static constexpr const char* _myArray[10] = {"Second"}; 
}; 

Ein weiterer Grund ist mit aktuellen Klasse als Template-Argument von Template-Klasse derieve:

class Base {/*...*/}; 

template<typename T> 
class GimmeArray 
{ 
    static const char* _myArray[10]; 
}; 

class InheritedThird : public Base, public GimmeArray<InheritedThird> 
{/*...*/}; 

class InheritedFourth : public Base, public GimmeArray<InheritedFourth> 
{/*...*/}; 

template<typename T> 
const char* GimmeArray<T>::_myArray[10] = {"Not specialized"}; 
template<> 
const char* GimmeArray<InheritedThird>::_myArray[10] = {"Third"}; 
template<> 
const char* GimmeArray<InheritedFourth>::_myArray[10] = {"Fourth"}; 
+0

IMHO wäre das ein Overkill in seinem Fall. Er sollte nur die statische entfernen und behandeln das Array als Mitglied ... – Nidhoegger

+0

Ich habe Ihren ersten Ansatz versucht. Es gibt unter fehler- constexpr statisches Datenelement '_myArray' muss Initialisierung hat FYI: base.h [erklärt] statisch constexpr const char * _myArray [10]; Child1.CPP statisch consxpr const char statisch consxpr const char * Child1 :: _ myArray [3] = {"rot", "grün", "blau"}; Child2.CPP statisch consExpr const char * Child1 :: _ myArray [3] = {"schwarz", "weiß", "braun"}; Was könnte falsch mit mir sein? – mirzapinku

+0

Haben Sie C++ 11 aktiviert? Wenn nein, entferne = und darüber hinaus und definiere Arrays außerhalb der Klassen – xinaiz

1

statische Variable kann einmal initialisiert werden. Bei der Initialisierung des statischen Members teilen Sie dem Compiler mit, in welcher Kompilierungseinheit diese statische Variable steht. Sie haben die Variable bereits in Child1 initialisiert, in Child2 ist dies nicht möglich.

0

Ziel:

ein Array von Wörtern Stellen, gespeichert einmal für jede abgeleitete Klasse. Alle Instanzen der gleichen Klasse müssen das gleiche Wortfeld teilen.

Der Zugriff auf das freigegebene Array muss polymorph sein, damit ein Beobachter Zugriff auf das Array haben kann, ohne den genauen Typ des Objekts zu kennen.

In diesem Fall hätte ich eine nicht-polymorphe Schnittstellenfunktion für die Basisklasse, die auf eine polymorphe Implementierung verweist.

Die Implementierung wird einmal pro abgeleiteter Klasse definiert und soll einen Verweis auf ein statisches const-Array von Wörtern liefern.

Als statisches const garantiert C++, dass es bei der ersten Verwendung erstellt wird. C++ 11 wird garantieren, dass die Konstruktion atomar ist.

etwas wie folgt aus:

#include <array> 
#include <iostream> 
#include <memory> 

using words_array = std::array<const char*, 3>; 

struct has_words_base 
{ 
public: 
    const words_array& get_words() const 
    { 
     return get_words_impl(); 
    } 

private: 
    virtual const words_array& get_words_impl() const 
    { 
     static const words_array _ { "grey", "black", "brown" }; 
     return _; 
    } 

}; 

struct blue_words : has_words_base 
{ 
private: 
    virtual const words_array& get_words_impl() const override 
    { 
     static const words_array _ { "blue", "cyan", "indigo" }; 
     return _; 
    } 

}; 

struct red_words : has_words_base 
{ 
private: 
    virtual const words_array& get_words_impl() const override 
    { 
     static const words_array _ { "red", "vermillion", "scarlet" }; 
     return _; 
    } 
}; 


void test(const has_words_base& ob) 
{ 
    auto sep = ""; 
    for (auto&& w : ob.get_words()) { 
     std::cout << sep << w; 
     sep = ", "; 
    } 
    std::cout << std::endl; 

} 

int main() 
{ 
    test(*std::make_unique<has_words_base>()); 
    test(*std::make_unique<blue_words>()); 
    test(*std::make_unique<red_words>()); 

} 

erwartete Ausgabe:

grey, black, brown 
blue, cyan, indigo 
red, vermillion, scarlet