Nach längerer Zeit beschäftige ich mich mal wieder mit C++, wobei ich sicher nie über die Anfänge hinaus gekommen bin.
Um mich fit zu machen, verwende ich Übungen aus diesem Buch:
Die C++-Challenge
Eine Aufgabe lautet, einen String als Titel auszugeben, indem jedes Wort groß geschrieben wird (der Wortanfang):
"the c++ challenger"
erwartet wird:
"The C++ Challenger"
Ich habe diese Aufgaben folgendermassen gelöst (VisualStudio):
[CODE lang="cpp" title="CapitalizeWords.cpp"]#include <iostream>
void capitalizeWords(
std::string& strToCapitalize)
{
if (strToCapitalize.size() < 1)
{
return;
}
strToCapitalize[0] = std::toupper(strToCapitalize[0]);
for (int i = 1; i < strToCapitalize.size() - 1; ++i)
{
if (strToCapitalize == ' ')
{
strToCapitalize[i + 1] = std::toupper(strToCapitalize[i + 1]);
}
}
}
int main()
{
std::string strToCapitalize("the c++ challenger");
std::cout << strToCapitalize << std::endl;
capitalizeWords(strToCapitalize);
std::cout << strToCapitalize << std::endl;
}
[/CODE]
Beim Entwickeln hatte ich einen Fehler, ich habe den String nicht als Referenz an die Funktion capitalizeWords übergeben.
[CODE lang="cpp" title="CapitalizeWords.cpp mit Fehler keine Übergabe per Referenz"]#include <iostream>
void capitalizeWords(
std::string strToCapitalize)
{
if (strToCapitalize.size() < 1)
{
return;
}
strToCapitalize[0] = std::toupper(strToCapitalize[0]);
for (int i = 1; i < strToCapitalize.size() - 1; ++i)
{
if (strToCapitalize == ' ')
{
strToCapitalize[i + 1] = std::toupper(strToCapitalize[i + 1]);
}
}
}
int main()
{
std::string strToCapitalize("the c++ challenger");
std::cout << strToCapitalize << std::endl;
capitalizeWords(strToCapitalize);
std::cout << strToCapitalize << std::endl;
}
[/CODE]
Erschreckend finde ich , dass beide Varianten problemlos kompilieren, offensichtlich kann in C++ die linke Seite einer Zuweisung bestimmen, was passiert.
Später fiel mir ein, dass in der falschen Variante ein Kopieren statt findet und am Ende der Funktion capitalizeWords der Destruktor aufgerufen werden müsste.
Leider weiss ich nicht, wie man sich anzeigen lassen kann, was C++ da eigentlich macht.
Ich habe irgendwo (wahrscheinlich iX) mal was gelesen über
C++ Insights
C++ Insights zeigt mir in der falschen Variante folgendes:
[CODE lang="cpp" title="StringCapitalize ohne Übergabe als Referenz als Ausgabe von C++ Insights"]#include <iostream>
void capitalizeWords(std::basic_string<char> strToCapitalize)
{
if(strToCapitalize.size() < 1) {
return;
}
strToCapitalize.operator[](0) = static_cast<char>(toupper(static_cast<int>(strToCapitalize.operator[](0))));
for(int i = 1; static_cast<unsigned long>(i) < (strToCapitalize.size() - 1); ++i) {
if(static_cast<int>(strToCapitalize.operator[](i)) == static_cast<int>(' ')) {
strToCapitalize.operator[](static_cast<unsigned long>(i + 1)) = static_cast<char>(toupper(static_cast<int>(strToCapitalize.operator[](static_cast<unsigned long>(i + 1)))));
}
}
}
int main()
{
std::string strToCapitalize = std::basic_string<char>("the c++ challenger", std::allocator<char>());
std:
perator<<(std::cout, strToCapitalize).operator<<(std::endl);
capitalizeWords(std::basic_string<char>(strToCapitalize));
std:
perator<<(std::cout, strToCapitalize).operator<<(std::endl);
}
[/CODE]
Der Destruktor des Parameter-Strings strToCapitalize wird nicht aufgerufen.
Hätte ich jetzt ein Speicherloch oder zeigt mir C++ Insights den Destruktor nicht an?
Vielen Dank
Um mich fit zu machen, verwende ich Übungen aus diesem Buch:
Die C++-Challenge
Eine Aufgabe lautet, einen String als Titel auszugeben, indem jedes Wort groß geschrieben wird (der Wortanfang):
"the c++ challenger"
erwartet wird:
"The C++ Challenger"
Ich habe diese Aufgaben folgendermassen gelöst (VisualStudio):
[CODE lang="cpp" title="CapitalizeWords.cpp"]#include <iostream>
void capitalizeWords(
std::string& strToCapitalize)
{
if (strToCapitalize.size() < 1)
{
return;
}
strToCapitalize[0] = std::toupper(strToCapitalize[0]);
for (int i = 1; i < strToCapitalize.size() - 1; ++i)
{
if (strToCapitalize == ' ')
{
strToCapitalize[i + 1] = std::toupper(strToCapitalize[i + 1]);
}
}
}
int main()
{
std::string strToCapitalize("the c++ challenger");
std::cout << strToCapitalize << std::endl;
capitalizeWords(strToCapitalize);
std::cout << strToCapitalize << std::endl;
}
[/CODE]
Beim Entwickeln hatte ich einen Fehler, ich habe den String nicht als Referenz an die Funktion capitalizeWords übergeben.
[CODE lang="cpp" title="CapitalizeWords.cpp mit Fehler keine Übergabe per Referenz"]#include <iostream>
void capitalizeWords(
std::string strToCapitalize)
{
if (strToCapitalize.size() < 1)
{
return;
}
strToCapitalize[0] = std::toupper(strToCapitalize[0]);
for (int i = 1; i < strToCapitalize.size() - 1; ++i)
{
if (strToCapitalize == ' ')
{
strToCapitalize[i + 1] = std::toupper(strToCapitalize[i + 1]);
}
}
}
int main()
{
std::string strToCapitalize("the c++ challenger");
std::cout << strToCapitalize << std::endl;
capitalizeWords(strToCapitalize);
std::cout << strToCapitalize << std::endl;
}
[/CODE]
Erschreckend finde ich , dass beide Varianten problemlos kompilieren, offensichtlich kann in C++ die linke Seite einer Zuweisung bestimmen, was passiert.
Später fiel mir ein, dass in der falschen Variante ein Kopieren statt findet und am Ende der Funktion capitalizeWords der Destruktor aufgerufen werden müsste.
Leider weiss ich nicht, wie man sich anzeigen lassen kann, was C++ da eigentlich macht.
Ich habe irgendwo (wahrscheinlich iX) mal was gelesen über
C++ Insights
C++ Insights zeigt mir in der falschen Variante folgendes:
[CODE lang="cpp" title="StringCapitalize ohne Übergabe als Referenz als Ausgabe von C++ Insights"]#include <iostream>
void capitalizeWords(std::basic_string<char> strToCapitalize)
{
if(strToCapitalize.size() < 1) {
return;
}
strToCapitalize.operator[](0) = static_cast<char>(toupper(static_cast<int>(strToCapitalize.operator[](0))));
for(int i = 1; static_cast<unsigned long>(i) < (strToCapitalize.size() - 1); ++i) {
if(static_cast<int>(strToCapitalize.operator[](i)) == static_cast<int>(' ')) {
strToCapitalize.operator[](static_cast<unsigned long>(i + 1)) = static_cast<char>(toupper(static_cast<int>(strToCapitalize.operator[](static_cast<unsigned long>(i + 1)))));
}
}
}
int main()
{
std::string strToCapitalize = std::basic_string<char>("the c++ challenger", std::allocator<char>());
std:
capitalizeWords(std::basic_string<char>(strToCapitalize));
std:
}
[/CODE]
Der Destruktor des Parameter-Strings strToCapitalize wird nicht aufgerufen.
Hätte ich jetzt ein Speicherloch oder zeigt mir C++ Insights den Destruktor nicht an?
Vielen Dank