String einlesen lassen (Klassen)
-
@mmm_1482_ dann erstell dir doch eine methode, die
cin >> name
aufruft.
-
@mmm_1482_
Wenn du diese unsäglichen getter/setter verwenden willst, musst du den Namen in einen String einlesen und dann damit set aufrufen.
-
@Wade1234
habe ja bereits die getter und setter dazu gemacht. und wenn ich selbst einen Namen initialisiere, dann funktioniert es auch. Aber ich möchte, dass der Benutzer den Namen eingibt
-
-
@Wade1234 perfekt das hat funktioniert! Vielen dank
-
@mmm_1482_ im hinblick auf oop ist das natürlich vorbildlich, geschwindigkeitsmäßig wird da aber wieder kopiert und alles ist langsam.
-
@Wade1234 ja ich weiß.. nur müssen wir das für die Prüfung leider drauf haben
-
@mmm_1482_ achso. ja also generell kannst du dir merken, dass du für jede popelige variable eine solche set-methode erstellen darfst, die dann den übergebenen wert kopiert. dadurch ist das dann alles schön abgesichert, aber gängige computerspiele laufen dann entsprechend langsam.
-
@Wade1234 sagte in String einlesen lassen (Klassen):
@mmm_1482_ achso. ja also generell kannst du dir merken, dass du für jede popelige variable eine solche set-methode erstellen darfst, die dann den übergebenen wert kopiert. dadurch ist das dann alles schön abgesichert, aber gängige computerspiele laufen dann entsprechend langsam.
Ordentlich implementiert sind Getter/Setter unter Optimierungen nicht lansamer als direkter Zugriff auf die Variablen (
const&
-Getter und Setter, die unnötige Kopien vermeiden, z.B. by value-Parameter + Move).Was aber definitiv stimmt, ist dass sie ein ziemlicher Schlepp zu implementieren sind und den Code mit jeder Menge Boilerplate aufblähen. Daher bin ich auch kein Fan davon.
Sie haben aber nicht von der Hand zu weisende Vorteile: Ein einziges Interface um von außen auf Instanzattribute zuzugreifen, an das man bei Bedarf noch ein Stück zusätzlichen Code hängen kann.
Manchmal wünsche ich mir sowas wie C#-Properties auch für C++. Es wäre schon manchmal nützlich Member-Zugriffe mit zusätzlichem Code versehen zu können, ohne das Interface so verändern zu müssen, dass man sämtlichen Code anpassen muss. Andererseits kann man aber auch Klassen so bauen, dass den Anwender nicht zu interessieren braucht, was für Attribute die alle haben - nur was für eine Funktionalität sie exponieren.
-
@Wade1234 sagte in String einlesen lassen (Klassen):
geschwindigkeitsmäßig wird da aber wieder kopiert und alles ist langsam.
So ein Quatsch.
-
@Swordfish sagte in String einlesen lassen (Klassen):
@Wade1234 sagte in String einlesen lassen (Klassen):
geschwindigkeitsmäßig wird da aber wieder kopiert und alles ist langsam.
So ein Quatsch.
du wiederholst dich......
-
Wenn du Blödsinn schreibst, dass "gängige Computerspiele [...] dann entsprechend langsam [laufen]", dann spendiere ich @Swordfish sogar noch die Soße zum Quatsch
Tipp: schau dir auf godbolt an, was wirklich passiert. Und wenn es Unterschiede gibt, beweise mit einem Profiler, dass das wirklich die Ursache ist.
-
ja da wird dann operator= aufgerufen, welches dann den inhalt kopiert.
-
@Wade1234 tu was @wob gesagt hat.
-
@Swordfish habe ich. operator= wird aufgerufen und laut http://www.cplusplus.com/reference/string/string/operator=/ wird der inhalt kopiert.
-
@Wade1234 sagte in String einlesen lassen (Klassen):
@Swordfish habe ich. operator= wird aufgerufen und laut http://www.cplusplus.com/reference/string/string/operator=/ wird der inhalt kopiert.
Ich verstehe nicht, was das mit dem Thema "getter und setter", die deiner Meinung nach alles langsam machen, zu tun haben sollte.
-
@wob sagte in String einlesen lassen (Klassen):
@Wade1234 sagte in String einlesen lassen (Klassen):
@Swordfish habe ich. operator= wird aufgerufen und laut http://www.cplusplus.com/reference/string/string/operator=/ wird der inhalt kopiert.
Ich verstehe nicht, was das mit dem Thema "getter und setter", die deiner Meinung nach alles langsam machen, zu tun haben sollte.
naja dass da im gegensatz zum direkten schreiben ein weiterer kopiervorgang stattfindet.
-
@Wade1234 Code? Link zu godbolt?
-
@Wade1234 sagte in String einlesen lassen (Klassen):
naja dass da im gegensatz zum direkten schreiben ein weiterer kopiervorgang stattfindet.
Aber nicht, so wie @Finnegan schon geschrieben hat, wenn man
const &
Getter und Setter benutzt.
-
@Swordfish sagte in String einlesen lassen (Klassen):
@Wade1234 Code? Link zu godbolt?
direktzugriff:
// Type your code here, or load an example. #include <iostream> class MyClass { public: std::string mystring; }; int main() { MyClass myclass; std::cin >> myclass.mystring; return 0; }
MyClass::MyClass() [base object constructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor] nop leave ret MyClass::~MyClass() [base object destructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] nop leave ret main: push rbp mov rbp, rsp push rbx sub rsp, 40 lea rax, [rbp-48] mov rdi, rax call MyClass::MyClass() [complete object constructor] lea rax, [rbp-48] mov rsi, rax mov edi, OFFSET FLAT:_ZSt3cin call std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) mov ebx, 0 lea rax, [rbp-48] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov eax, ebx jmp .L7 mov rbx, rax lea rax, [rbp-48] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov rax, rbx mov rdi, rax call _Unwind_Resume .L7: add rsp, 40 pop rbx pop rbp ret __static_initialization_and_destruction_0(int, int): push rbp mov rbp, rsp sub rsp, 16 mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi cmp DWORD PTR [rbp-4], 1 jne .L10 cmp DWORD PTR [rbp-8], 65535 jne .L10 mov edi, OFFSET FLAT:_ZStL8__ioinit call std::ios_base::Init::Init() [complete object constructor] mov edx, OFFSET FLAT:__dso_handle mov esi, OFFSET FLAT:_ZStL8__ioinit mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev call __cxa_atexit .L10: nop leave ret _GLOBAL__sub_I_main: push rbp mov rbp, rsp mov esi, 65535 mov edi, 1 call __static_initialization_and_destruction_0(int, int) pop rbp ret
zugriff über einfachen setter (nebenbei erwähnt fast doppelt so lang):
// Type your code here, or load an example. #include <iostream> class MyClass { std::string mystring; public: void SetMystring(std::string str); }; void MyClass::SetMystring(std::string str) { mystring = str; } int main() { MyClass myclass; std::string str; std::cin >> str; myclass.SetMystring(str); return 0; }
MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >): push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov QWORD PTR [rbp-16], rsi mov rax, QWORD PTR [rbp-8] mov rdx, QWORD PTR [rbp-16] mov rsi, rdx mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) nop leave ret MyClass::MyClass() [base object constructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor] nop leave ret MyClass::~MyClass() [base object destructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] nop leave ret main: push rbp mov rbp, rsp push rbx sub rsp, 104 lea rax, [rbp-80] mov rdi, rax call MyClass::MyClass() [complete object constructor] lea rax, [rbp-112] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor] lea rax, [rbp-112] mov rsi, rax mov edi, OFFSET FLAT:_ZSt3cin call std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) lea rdx, [rbp-112] lea rax, [rbp-48] mov rsi, rdx mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) lea rdx, [rbp-48] lea rax, [rbp-80] mov rsi, rdx mov rdi, rax call MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) lea rax, [rbp-48] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] mov ebx, 0 lea rax, [rbp-112] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] lea rax, [rbp-80] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov eax, ebx jmp .L10 mov rbx, rax lea rax, [rbp-48] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] jmp .L7 mov rbx, rax .L7: lea rax, [rbp-112] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] lea rax, [rbp-80] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov rax, rbx mov rdi, rax call _Unwind_Resume .L10: add rsp, 104 pop rbx pop rbp ret __static_initialization_and_destruction_0(int, int): push rbp mov rbp, rsp sub rsp, 16 mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi cmp DWORD PTR [rbp-4], 1 jne .L13 cmp DWORD PTR [rbp-8], 65535 jne .L13 mov edi, OFFSET FLAT:_ZStL8__ioinit call std::ios_base::Init::Init() [complete object constructor] mov edx, OFFSET FLAT:__dso_handle mov esi, OFFSET FLAT:_ZStL8__ioinit mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev call __cxa_atexit .L13: nop leave ret _GLOBAL__sub_I_MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >): push rbp mov rbp, rsp mov esi, 65535 mov edi, 1 call __static_initialization_and_destruction_0(int, int) pop rbp ret
setter mit referenz:
// Type your code here, or load an example. #include <iostream> class MyClass { std::string mystring; public: void SetMystring(const std::string &str); }; void MyClass::SetMystring(const std::string &str) { mystring = str; } int main() { MyClass myclass; std::string str; std::cin >> str; myclass.SetMystring(str); return 0; }
MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&): push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov QWORD PTR [rbp-16], rsi mov rax, QWORD PTR [rbp-8] mov rdx, QWORD PTR [rbp-16] mov rsi, rdx mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) nop leave ret MyClass::MyClass() [base object constructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor] nop leave ret MyClass::~MyClass() [base object destructor]: push rbp mov rbp, rsp sub rsp, 16 mov QWORD PTR [rbp-8], rdi mov rax, QWORD PTR [rbp-8] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] nop leave ret main: push rbp mov rbp, rsp push rbx sub rsp, 72 lea rax, [rbp-48] mov rdi, rax call MyClass::MyClass() [complete object constructor] lea rax, [rbp-80] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor] lea rax, [rbp-80] mov rsi, rax mov edi, OFFSET FLAT:_ZSt3cin call std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) lea rdx, [rbp-80] lea rax, [rbp-48] mov rsi, rdx mov rdi, rax call MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) mov ebx, 0 lea rax, [rbp-80] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] lea rax, [rbp-48] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov eax, ebx jmp .L8 mov rbx, rax lea rax, [rbp-80] mov rdi, rax call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor] lea rax, [rbp-48] mov rdi, rax call MyClass::~MyClass() [complete object destructor] mov rax, rbx mov rdi, rax call _Unwind_Resume .L8: add rsp, 72 pop rbx pop rbp ret __static_initialization_and_destruction_0(int, int): push rbp mov rbp, rsp sub rsp, 16 mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi cmp DWORD PTR [rbp-4], 1 jne .L11 cmp DWORD PTR [rbp-8], 65535 jne .L11 mov edi, OFFSET FLAT:_ZStL8__ioinit call std::ios_base::Init::Init() [complete object constructor] mov edx, OFFSET FLAT:__dso_handle mov esi, OFFSET FLAT:_ZStL8__ioinit mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev call __cxa_atexit .L11: nop leave ret _GLOBAL__sub_I_MyClass::SetMystring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&): push rbp mov rbp, rsp mov esi, 65535 mov edi, 1 call __static_initialization_and_destruction_0(int, int) pop rbp ret
der kopiervorgang findet übrigens in zeile 11 statt.