2017-12-06 12 views
0

Ich habe ein Stück Arbeitscode, über den ich mir nicht sicher bin. Siehe unten für eine verspottete Version. Die jist davon ist ich habe eine Foo Klasse, eine ChildFoo Klasse und Bar Klasse, die eine Instanz von Foo hat. Foo stellt einige Schlüssel zu Bar dar, um ein json Wörterbuch zu analysieren. Bar ist generisch und wird mehrfach verwendet, Foo ist für jede Implementierung unterklassifiziert. nur verwendet seinen eigenen Namen anstelle einem bestimmten SchlüsselOverride öffentliche statische const Mitglieder in untergeordneten Klassen

Ich habe ein public static const std::string in Foo, der standardmäßig auf "" in diesem Fall die Bar Methode den Wert parsen. Ich überschreibe PARAM_VALUE in ChildFoo, weil es JSON-Wörterbuch ist komplizierter und bietet {value: [], type:[], ...}, während andere Implementierungen gerade {mName: []} zurückgeben.

foo.h:

class Foo 
{ 
public: 
    static const std::string PARAM_VALUE; 
} 

foo.cpp:

const std::string Foo::PARAM_VALUE = ""; 

Foo::Foo() 
{ 
... 
} 

ChildFoo.cpp:

const std::string Foo::PARAM_VALUE = "value"; 

ChildFoo::ChildFoo() : Foo() 
{ 
... 
} 

bar.h

class Bar 
{ 
private: 
    std::string mName; 
    ChildFoo * mFoo; 
} 

Bar.cpp:

Bar::Bar() 
{ 
... 
} 

int Bar::parseValue() 
{ 
    std::string key; 
    if (!mFoo->PARAM_VALUE.empty()) { 
     key = mFoo->PARAM_VALUE; 
    } 
    else { 
     key = mName; 
    } 
    ... 
} 

Ich nahm an, ich habe auf die Route der virtuellen Getter für diese Tasten nach unten gehen würde, aber dachte, ich würde versuchen, diese aus und war etwas überrascht, dass es funktioniert zu finden. Wenn ich darüber nachdenke, glaube ich, dass es funktioniert, weil Foo::PARAM_VALUE zur Kompilierungszeit von ChildFoo überschrieben wird, so dass die const zu diesem Zeitpunkt nicht restriktiv ist. Ich bin mir aber nicht ganz sicher.

Ist es nicht verwunderlich, dass das funktioniert? Wird das als OK angesehen? Gibt es irgendwelche Nachteile, die sich daraus ergeben könnten?

Cheers, Gary

+0

Verbindet es? Sie haben mehrere (verschiedene) Definitionen von 'const std :: string Foo :: PARAM_VALUE' -> ODR-Verletzung. – Jarod42

+0

Es kompiliert und läuft, wie ich es gerne würde. – GDYendell

Antwort

1

ich nicht davon überzeugt bin, dass Ihr Linker dies ermöglichen würde, ist das Verhalten sicherlich nicht definiert, wenn es funktioniert.

Ihr Code verletzt die eine Definitionsregel.

Sie können auf variable Shadowing zurückgreifen, wenn Sie wollen, aber bedenken Sie, dass dies nicht polymorph wäre. Wenn Sie Polymorphie wollen, müssen Sie virtuelle Funktionen verwenden.

+0

Könnten verschiedene Compiler sich darüber beschweren? Ich verwende gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18). – GDYendell

+0

Formal ist es die Link-Phase, die eine Beschwerde ausstellen sollte. – Bathsheba

Verwandte Themen