Mam następujący kod pracy:Dlaczego nie mogę zrobić w tej klasie zainicjowany `const const std :: string` element statyczny
#include <string>
#include <iostream>
class A {
public:
const std::string test = "42";
//static const std::string test = "42"; // fails
};
int main(void){
A a;
std::cout << a.test << '\n';
}
Czy istnieje dobry powód, dlaczego nie jest możliwe dokonanie test a static const
? Rozumiem przed C++ 11 było ograniczone przez standard. Pomyślałem, że C++ 11 wprowadził in-class initialization, aby uczynić go trochę bardziej przyjaznym. Też nie takie semantyczne są dostępne dla typu integralnego od dłuższego czasu.
Oczywiście to działa z out-of inicjalizacji klasy w formie const std::string A::test = "42";
Myślę, że jeśli można zrobić to non-static, to problem leży w jednym z tych dwóch. Inicjowanie go poza zasięgiem klasy (zwykle const
s są tworzone podczas tworzenia obiektu). Ale nie sądzę, że to jest problem, jeśli tworzysz obiekt niezależny od jakichkolwiek innych członków klasy. Drugi ma wiele definicji dla statycznego elementu. Na przykład. jeśli byłby zawarty w kilku plikach .cpp
, lądując w kilku plikach obiektowych, a następnie linker miałby problemy podczas łączenia tych obiektów razem (na przykład w jeden plik wykonywalny), ponieważ zawierałyby kopie tego samego symbolu. Według mnie jest to dokładnie równe sytuacji, w której dostarcza się prawa poza klasą w deklaracji klasy w nagłówku, a następnie obejmuje ten wspólny nagłówek w więcej niż jednym miejscu. Jak pamiętam, prowadzi to do błędów linkera.
Jednak teraz odpowiedzialność za manipulację tą jest przenoszona na użytkownika/programistę. Jeśli ktoś chce mieć bibliotekę z static
, musi podać definicję poza klasą, skompilować ją do oddzielnego pliku obiektowego, a następnie połączyć ze sobą wszystkie inne obiekty, mając w związku z tym tylko jedną kopię binarnej definicji symbol.
Przeczytałem odpowiedzi w Do we still need to separately define static members, even if they are initialised inside the class definition? i Why can't I initialize non-const static member or static array in class?.
nadal chcieliby wiedzieć:
- Czy tylko standardowe rzeczy, czy tam jest głębszy rozumowanie za tym stoi?
- Można to obejść przy pomocy mechanizmów literowych
constexpr
i zdefiniowanych przez użytkownika . Zarówno clang, jak i g ++ twierdzą, że zmienna nie może mieć typu nie-literalnego. Może uda mi się to zrobić. (Może z jakiegoś powodu jest to również zły pomysł) - Czy to naprawdę duży problem, aby linker mógł umieścić tylko jeden egzemplarz symbolu: ? Ponieważ jest to
static const
, wszystkie powinny być niezmiennymi kopiami o dokładności binarnej .
Plese również komentarz, jeśli brakuje mi czegoś lub czegoś nie rozumiem.
Jeśli chodzi o statykę, można inicjować tylko całki typu "const" i wyliczenia w miejscu deklaracji. – juanchopanza
@juanchopanza Wiem o tym. Myślałem, że w C++ 11 można go pokonać. – luk32
Myślę, że wskazałeś w 3. jednym z problemów. Tak, byłoby to wykonalne, ale wymagałoby to specjalnego przypadku, ponieważ w przeciwnym razie linker po prostu nie "lubi" wielu definicji. – ondrejdee