What is the difference between string::at and string::operator[]?
Yes, there is one major difference: using .at()
does a range check on index passed and throws an exception if it's over the end of the string while operator[]
just brings undefined behavior in that situation.
Difference between std::string [] operator and at()
Your second program is malformed. It's not using std::string::operator[]
at all.
string * ps = new string(str);
ps[0] = 'n';
Not only does std::string
support the []
operator, every pointer to a type also supports the []
operator. It's how C style arrays work, and it's what you're doing in the code above.
ps
isn't a string
. It's a pointer. And ps[0]
is the one string, not unlike *ps
.
You probably wanted this instead:
#include <iostream>
#include <string>
using namespace std;
void remodel(string & str){
string * ps = new string(str);
(*ps)[0] = 'n';
// or: ps->operator[](0) = 'n';
cout<<*ps<<endl;
delete ps;
}
int main(){
string str = "Hello world";
remodel(str);
cin.get();
return 0;
}
Or, more idiomatically, use this instead:
#include <iostream>
#include <string>
using namespace std;
void remodel(string & str){
string ps = str;
ps[0] = 'n';
cout<<ps<<endl;
}
int main(){
string str = "Hello world";
remodel(str);
cin.get();
return 0;
}
Difference between c++ string append and operator +=
According to the standard concerning string::op+= / online c++ standard draft, I wouldn't expect any difference:
basic_string& operator+=(const basic_string& str);
(1) Effects: Calls append(str).
(2) Returns: *this.
Difference between indexing operator ([]) of string and string_view
The difference is a std::string is guaranteed to be NUL terminated - a view is not. Therefor a std::string always has a valid value at the 0th position.
For a std::string:
If pos == size(), a reference to the character with value CharT() (the null character) is returned.
http://en.cppreference.com/w/cpp/string/basic_string/operator_at
How comparison operator for strings works in C++, if strings are numbers?
The behaviour of your code is undefined.
The const char[]
literals you have entered decay to const char*
pointers for the purpose of comparison.
And the behaviour of the comparison operators on pointers is only defined if the pointers are part of the same array; which yours are not.
If you suffix the literals with an s, e.g."3"s
then C++14 onwards will treat that as a std::string and will perform a lexographic comparison.
std::string::assign vs std::string::operator=
Both are equally fast, but = "..."
is clearer.
If you really want fast though, use assign
and specify the size:
test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
// or
test2.assign("Hello again", 11);
That way, only one allocation is needed. (You could also .reserve()
enough memory beforehand to get the same effect.)
Difference between std::string's operator[] and const operator[]
They both return references to the internal member of the string.
The first method is defined as a const method (the last const) and as such promises not to change any members. To make sure you can;t change the internal member via the returned reference this is also const.
const char& operator[](int i) const
// ^^^^^ this means the method will not change the state
// of the string.
//^^^^^^^^^^^ This means the object returned refers to an internal member of
// the object. To make sure you can't change the state of the string
// it is a constant reference.
This allows you to read members from the string:
std::string const st("Plop is here");
char x = st[2]; // Valid to read gets 'o'
st[1] = 'o'; // Will fail to compile.
For the second version it say we return a reference to an internal member. Neither promise that the object will not be altered. So you can alter the string via the reference.
char& operator[](int i)
// ^^^^^ Returns a reference to an internal member.
std::string mu("Hi there Pan");
char y = mu[1]; // Valid to read gets 'i'
mu[9] ='M'; // Valid to modify the object.
std::cout << mu << "\n"; // Prints Hi there Man
Is it true that the second one is duplicating the string? and why?
No. Because it does not.
Difference between string.concat and the + operator in string concatenation
str.concat(" game");
has the same meaning as str + " game";
. If you don't assign the result back somewhere, it's lost. You need to do:
str = str.concat(" game");
Concatenate 2 string using operator+= in class C++
In many of your constructors, you do not set length
which leaves it with an indeterminate value - and reading such values makes the program have undefined behavior. So, first fix that:
#include <algorithm> // std::copy_n
// Constructor with no arguments
String::String() : data{new char[1]{'\0'}}, length{0} {}
// Constructor with one argument
String::String(const char* s) { // note: const char*
if (s == nullptr) {
data = new char[1]{'\0'};
length = 0;
} else {
length = std::strlen(s);
data = new char[length + 1];
std::copy_n(s, length + 1, data);
}
}
// Copy Constructor
String::String(const String& source) : data{new char[source.length + 1]},
length{source.length}
{
std::copy_n(source.data, length + 1, data);
}
// Move Constructor
String::String(String&& source) : String() {
std::swap(data, source.data);
std::swap(length, source.length);
}
In operator+=
you are trying to use the subscript operator, String::operator[]
, but you haven't added such an operator so instead of s[i]
, use s.data[i]
:
String& String::operator+=(const String& s) {
unsigned len = length + s.length;
char* str = new char[len + 1];
for (unsigned j = 0; j < length; j++) str[j] = data[j];
for (unsigned i = 0; i < s.length; i++) str[length + i] = s.data[i];
str[len] = '\0';
delete[] data; // note: delete[] - not delete
length = len;
data = str;
return *this;
}
If you want to be able to use the subscript operator on String
objects, you would need to add a pair of member functions:
class String {
public:
char& operator[](size_t idx);
char operator[](size_t idx) const;
};
char& String::operator[](size_t idx) { return data[idx]; }
char String::operator[](size_t idx) const { return data[idx]; }
And for String s3 = s1 + s2;
to work, you need a free operator+
overload:
String operator+(const String& lhs, const String& rhs) {
String rv(lhs);
rv += rhs;
return rv;
}
Also, to support printing a String
like you try in your alternative main
function, you need an operator<<
overload. Example:
class String {
friend std::ostream& operator<<(std::ostream& os, const String& s) {
os.write(s.data, s.length);
return os;
}
};
Full demo
Related Topics
Are the "Usual Arithmetic Conversions" and the "Integer Promotions" the Same Thing
When Should I Use the Keyword "Typename" When Using Templates
Boost::Asio + Std::Future - Access Violation After Closing Socket
Setting Pointer to Arbitrary Dimension Array
Timestamps for Embedded System
Why Is My Double or Int Value Is Always 0 After Division
Strange Behavior of Const_Cast
How to Do Static_Assert with MACros
C++: Initialization of Inherited Field
Why "Foo F(Bar());" Can Be a Declaration of a Function That Takes Type Bar and Returns Type Foo
Default Move Constructor in Visual Studio 2013 (Update 3)
How to Legally Reinterpret_Cast Between Layout-Compatible Standard-Layout Types
Alpha Rendering Difference Between Opengl and Webgl
What am I Allowed to Do with a Static, Constexpr, In-Class Initialized Data Member
Convert Inline Assembly Code to C++
Why Is a Default Constructor Required When Storing in a Map
Why Can't I Use a "Break" Statement Inside a Ternary Conditional Statement in C++
How to Make a C++ Struct Value-Initialize All Pod Member Variables