Create String object from std::string by overloading = operator - c++

I've tried several options but my compiler does not pick up the operator overloading or something else is wrong. I'm using XCode 4.5.2 with default Apple LLVM compiler 4.1.
The error I get is this: Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]'
on these lines:
CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
My .h code:
CCString& operator= (const std::string& str);
// CCString& operator= (const char* str); // this doesn't work either
const CCString& operator = (const char *);
My .cpp code (even though this is irelevant):
CCString& CCString::operator= (const std::string& str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
const CCString& CCString :: operator = (const char* str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
Your help is very appreciated, thanks!

The error message Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]' suggests that you are assigning a char array to a pointer to cocos2d::CCString.
This should work:
char bar[] = "ABCD";
cocos2d::CCString foo;
foo = bar;

CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
What the heck is this supposed to do? Declaring a pointer does not generate any object except the pointer itself. So basically, for this to "work", there would need to be another CCString object around already, that happens to represent the string "TEST". But even if that's given, how is C++ supposed to know which one to point to? It would need to look "TEST" up in some kind of e.g. hash map.
None of this makes any sense. Change your code to either
Direct use of object on stack:
cocos2d::CCString s_piece;
s_piece = "TEST";
Assigning new content to an object that resides somewhere else. You'd normally use a reference for this, e.g.
void assign_test_to(cocos2d::CCString& target) {
target = "TEST";
}
it's also possible with a pointer
void assign_test_to_ptr(cocos2d::CCString* target) {
*target = "TEST";
}
but don't do that unless you have a specific reason to.
In principle, there's another possibility:
cocos2d::CCString* s_piece_locks = new CCString;
*s_piece_locks = "TEST";
but you want to avoid this, as it can very easily lead to memory leaks. What would be ok is
std::unique_ptr<cocos2d::CCString> s_piece_locks = new CCString;
*s_piece_locks = "TEST";

Related

Overloading Operators with char c++

I am working on a homework for class on overloading operators. The problem I am having is with a char.
RetailItem &RetailItem::operator=(const RetailItem &objRetail) {
this->description = objRetail.getDescription();
this->unitsOnHand = objRetail.getUnitsOnHand();
this->price = objRetail.getPrice();
return *this;
}
I am getting a message on Visual Studio:
a value of type const char * cannot be assigned to an entity of type char *.
I have done some research and not found anything. If anyone can help, thanks in advance.
EDIT:
I will add the getDescription function to provide more information. Also the description is a *char.
const char *RetailItem::getDescription() const{
return description;
}
Probably RetailItem::description is char* and RetailItem::getDescription casts this char* to const char* and returns that. You can add const qualifiers implicitly, but you cannot remove them the same way in the assignment:
this->description = objRetail.getDescription();
And you probably shouldn't. This will make two RetailItems referring to the same resource without managing its lifetime properly, as well as not freeing the memory held previously (if it is indeed a pointer to a dynamically allocated array).
This boils down to: you should prefer using std::string over arrays.
Reason might be mismatch between data type of "member variables" which you used in the class and the return values of the function.
const char *RetailItem::getDescription() const{
return description;
}
Remove const before function , keep it char *RetailItem::getDescription() const only .It should work

Overloading operator= or operator[] using const char* and/or string

I've been scouring google and stackoverflow for so-far no clear answer to this, so I'm asking directly...
I made a bitmap font class and I'd like to use an assignment operator: operator=(const char*) to assign a string literal to the text of the class.
Note: I'd also like to assign using string, string* and char*...
For example:
class BitmapText{
private:
std::string _text;
public:
void operator=(const char* _t){
_text = _t;
}
/*I've also tried another iteration of this operator using
BitmapText& operator=(const char* _t){
_text = _t;
return *this;
}
*/
BitmapText(){}
~BitmapText(){}
};
BitmapText* t1 = new BitmapText();
t1 = "Hello World"
Assigning the char string to the BitmapText object yields something like the following:
Assigning to 'BitmapText*' from 'const char[12]' incompatible type.
I'm sure there's a very good reason for this. But It can be done with the string class. I looked into the string class and it is typedef'd from:
typedef basic_string<char, char_traits<char>, allocator<char> > string;
Is this why I can assign a char array to the string class? Because it somehow seems to inherit characteristics of char? Can I overload the way I'm trying without such a complicated implementation?
My second question is (I think) along the same lines:
I want to use the operator[](const char* _name) to return a child object who's name matches the _name value.
Every operator overloading example I look at uses right-hand operands of the same class type as the one being overloaded. I have read however, you can use different data types, and we can clearly use a char* to assign a value to a std::string object...
What am I missing?
Any and all help is so greatly appreciated.
Define the operator the following way
BitmapText & operator =( const std::string &t )
{
_text = t;
return *this;
}
It can be used for objects of type std::string and for objects of type char * because there is implicit conversion from const char * to std::string due to a conversion constructor of class std::string.
As for this code snippet
BitmapText* t1 = new BitmapText();
t1 = "Hello World"
^^^ ^^
then it has to be rewritten the following way
BitmapText* t1 = new BitmapText();
*t1 = "Hello World";
This statement
t1 = "Hello World";
is wrong because you are trying to assign a pointer of type const char * to a pointer of type BitmapText *.
You're trying to assign to t1, which is not a BitmapText but a pointer to a BitmapText;
If you do *t1 = "Hello World"; it should work.
You are trying to assign to a pointer, the address of a string literal.
Instead try:
BitmapText* t1 = new BitmapText();
(*t1)= "Hello World";

Implicitly convert from std::string to eastl::string

I was using string class from stl std::string now I want to replace everything with eastl. So the easy question:
eastl::string obj = std::string("test");
error: conversion from ‘the::string {aka std::basic_string}’ to
non-scalar type ‘eastl::string {aka eastl::basic_string}’
requested
Is it possible to automate conversion between this types?
eastl::string obj1 = "test"; // works out of the box
eastl::string obj2 = std_string.c_str(); // equivalent to above
eastl::string obj3(&std_string[0], // another option
&std_string[0]+std_string.size());
No, not if eastl::string does not define a copy constructor/assignment operator for std::string.
The simplest way to go from a std::string to an eastl::string would be to use the .c_str() method to get a pointer to the std::string's internal char array
std::string ss("hello");
eastl::string es = ss.c_str();
You can add your own if you want to modify the library. Although that is probably a bad idea
simple example:
class MyString {
private:
char *str;
public:
MyString(const std::string &s) {
str = new char[s.length() + 1]; /* allocate */
strcpy(this->str, s.c_str()); /* copy */
}
~MyString() {
delete [] str;
}
};
Then you can create a new MyString with:
MyString ms = std::string("hello");
These classes are not compatible. eastl::string has no constructor with std::string argument. So you should use something like this:
srd::string stlstr = "test";
eastl::string eastlstr= strlstr.c_str();

issue with pointers and constructors

The following code doesn't work:
class String{
public:
char* str;
int* counter;
String(){
str = NULL;
counter = new int;
*counter = 1;
};
String(const char* str1){
String();
str = new char[strlen(str1)+1];
strcpy(str, str1);
};
};
I've changed the call to the empty constructor and replaced it with its internals, and now the following code works:
class String{
public:
char* str;
int* counter;
String(){
str = NULL;
counter = new int;
*counter = 1;
};
String(const char* str1){
//String();
str = new char[strlen(str1)+1];
strcpy(str, str1);
counter = new int;
*counter = 1;
};
Can you please suggest why?
Thanks, Li.
"Doesn't work" is not a good description of the problem. But you apparently tried to invoke a constructor from another one. That's called constructor delegation and is not (yet) supported by C++.
BTW, a class like this should get a user-defined copy constructor, assignment operator and destructor.
It seems to me you are trying to invoke a constructor from another constructor of the same class, like you would in C# for example. Unfortunately you cannot do this in C++ (at least no easy way I know of). You need to either have a private method or duplicate the code.
In the current C++, constructors cannot call each other. That's called "chaining constructors", or "delegating constructors" and is supported by the new C++0x standard but with a different syntax than the one you are using.
Off-topic, why do you use a pointer to int for the counter?
Calling String(); actually creates a temporary object and then throws it away again. It won't call the other constructor.
The call 'String();' creates an unnamed temporary object of type String that is destroyed immediately. The second code snippet is fine.
However you should really relook at the members of your class. Use std::string instead of raw char pointer. Also int *counter does not look very intuitive
You are allowed to do something like this:
class String{
public:
char* str;
int* counter;
private:
void initialize() {
str = NULL;
counter = new int;
*counter = 1;
}
public:
String(){
initialize();
};
String(const char* str1){
initialize();
str = new char[strlen(str1)+1];
strcpy(str, str1);
};
};
why is the counter a pointer ?
What does not work ? compilation error ?
Probably calling the constructor inside another is not well supported on your compiler ?
what platform ?

C++ : error: invalid operands of types ‘String*’ and ‘const char [7]’ to binary ‘operator+’

I'm learning cpp and In my last assignment I am rewriting the std::string class.
so here is an outline of my code:
string class:
class String {
public:
String(const char* sInput) {
string = const_cast<char*> (sInput);
}
const String operator+(const char* str) {
//snip
print();
}
void print() {
cout<<string;
}
int search(char* str) {
}
private:
char* string;
int len;
};
Oh and I have to say I tried to declare the method as String* operator+(const char* str) and as const String& operator+(const char* str) with no change.
And here is how I run it:
int main(int argc, char* argv[]) {
String* testing = new String("Hello, "); //works
testing->print();//works
/*String* a = */testing+"World!";//Error here.
return 0;
}
The full error goes like such:
foobar.cc:13: error: invalid operands
of types ‘String*’ and ‘const char
[7]’ to binary ‘operator+’
I looked up on Google and in the book I am learning from with no success.
any one with suggestions? (I am pretty sure I am doing something foolish you will have to forgive me I am originally a PHP programmer) can any one point me to what am I missing?
You probably don't want to use a pointer to your String class. Try this code:
int main(int argc, char* argv[]) {
String testing = String("Hello, "); //works
testing.print();//works
String a = testing+"World!";
return 0;
}
When defining new operators for C++ types, you generally will work with the actual type directly, and not a pointer to your type. C++ objects allocated like the above (as String testing) are allocated on the stack (lives until the end of the "scope" or function) instead of the heap (lives until the end of your program).
If you really want to use pointers to your type, you would modify the last line like this:
String *a = new String(*testing + "World!");
However, following the example of std::string this is not how you would normally want to use such a string class.
Your operator+ is defined for String and const* char, not for String*. You should dereference testing before adding it, i.e.:
String a = (*testing) + "World";
Though in this case I don't see the point in making testing a pointer in the fist place.
Edit: Creating a string without pointers would look like this:
String testing = "Hello, ";
or
String testing("Hello, ");
(both are equivalent).