@LongInteger:
Oczekuje się, że operator przypisania zrobi to samo co konstruktor kopiujący z tą tylko różnicą, że operator przypisania musi wpierw usunąć stary stan obiektu (np. zwolnić pamięć). Konstruktory zaś dostają obiekt niezaincjowany (bez starego stanu).
Bardzo ciekawe. Czy możesz podać przykład jak operator przypisania "zwalnia" stary stan obiektu ? Szczerze mówiąc nie wiem jak to osiągnąć
@_13th_Dragon:
Dla mnie (oraz wielu innych na tym forum) tak, zaś dla @zkubinski , szczerzę wątpię? Poza tym nie koniecznie konstruktor domyślny robi to samo co pusta lista inicjalizacyjna. Jak mawiał Mark Twain: - umiar jest potrzebny we wszystkim, łącznie z umiarem.
Rozważmy najprostszy wariant, weźmy za przykład (w duuużym uproszczeniu) mój program, który próbuję zrobić z zapisem pliku JSON. Mam najprostszy typ konstruktora jaki może być
ProstaKlasa::ProstaKlasa() : ipv4Address("127.0.0.1")
{
}
czyli według ciebie nie mogę dla tego typu konstruktora użyć
ProstaKlasa obiekt{};
Natomiast dla takiego konstruktora
SkomplikowanaKlasa::SkomplikowanaKlasa() : // tu ze dwadzieścia zmiennych do inicjalizacji
{
// tu konstruktor tworzy bardzo skomplikowany obiekt
}
to dla powyższego konstruktora według ciebie mogę już użyć ?
SkomplikowanaKlasa DuzyObiekt{};
Jaka jest różnica między jednym, a drugim użyciem { }
?
PS. czytałem podlinkowany artykuł i wnioski z niego są takie
-
Zawsze i wszędzie używaj { }
aby nie narobić sobie problemu z debugowaniem, autor nie wspominał aby nie używać { }
NAWET dla prostego konstruktora domyślnego.
-
O dziwo gdzieś mi się obiło o oczy, że standard C++11 wspiera zapis konstruktorów nawiasami { }
i nie widziałem potrzeby używania tego zapisu, aż do momentu przeczytania podlinkowanego artykułu. Myślę, że jest sens użycia { }
dla każdego przypadku konstruktora chociażby dla czytelności - czyli odróżnienia konstruktora od funkcji
Chyba, że masz na myśli taki zapis w najprostszej wersji
SkomplikowanaKlasa DuzyObiekt(InnyMniejszyObiekt{});
Co nie zmienia faktu, że użycie { }
NIE jest zabronione przy dosłownie każdym konstruktorze.
DOPISEK:
już chyba rozumiem po co używać { }
w konstruktorze - rozumiem, to tak, że to zastępuje listę inicjalizacyjną konstruktora - czyli jeżeli nie została zadeklarowana lista inicjalizacyjna, to żeby nadać "stan początkowy" obiektu używa się nawiasów klamrowych { }
więc dlatego kod który dałeś (przerobiłem po swojemu) bo jak zwykle lubisz udziwiać
#include <QVector>
#include <QDebug>
using namespace std;
int main()
{
QVector <int>v1(3,5); //tutaj nie zainicjalizuje się poprawnie
int i;
foreach(i, v1){
qDebug()<< i;
}
qDebug()<< Qt::endl;
QVector <int>v2{3,5}; //tutaj zainicjalizuje się poprawnie bo użyłem nawiasów klamrowych
int j;
foreach(j, v2){
qDebug()<< j;
}
return 0;
}
tylko nie rozumiem:
- jak samemu napisać konstuktor aby można było użyć nawiasów
{ }
aby możliwa była poprawna inicjalizacja parametrów konstruktora ? Poda ktoś przykład ?
- jak rozpoznać przypadek, że jest mi potrzebne użycie nawiasów
( )
albo { }