![]() |
| | #1 |
| Registered User Join Date: Oct 2008 Location: Leading lawn gnomes on the path to world domination! ;o)
Posts: 13
| Sorry to be a bother, but I needed some help wrapping my head around some syntax. I would like to apologize in advance for the long post. The book I'm reading from right now is trying to teach me how to make a class similar to #include <string>. However, there is some strange syntax that I'm not understanding. I've never posted here before, much less posted code, so please forgive me if I don't provide all the information you need. Also, I'm fairly new at programming. I've only been learning this for about 5 months or so. Code: class my_string {
private:
char *ptr;
public:
//Constructors and destructors that I understand, and functions I understand, so I
//see no need to post any of the code I do understand.
my_string& operator=(const my_string &object)
{cpy(object.ptr); return *this;}
my_string& operator=(char *s)
{cpy(char *s); return *this;}
operator char*() {return ptr;}
void cpy(char *s)
};
void my_string::cpy(char *s) {
delete [] ptr;
int n = strlen(s);
ptr = new char[n + 1];
strcpy(ptr, s);
}
Code: my_String& operator=(const my_string &object); Code: void cpy(char *s); void cpy(const my_string &object); Code: operator char*() Anyways, thank you to anyone who takes the time to answer this, and I apologize if this is something simple. I'm learning on my own, so I don't have a teacher or professor to ask. If I didn't provide enough information, or ask my questions in any coherent way, please let me know so I can try to clarify what I'm asking. |
| Lawn Gnomusrex is offline | |
| | #2 |
| The superheterodyne. Join Date: Dec 2005 Location: Ireland
Posts: 2,205
| That code doesn't work. This should... Code: class my_string {
private:
char *ptr;
public:
my_string& operator=(const my_string &object) {
cpy(object.ptr); return *this;
}
my_string& operator=(char *s) {
cpy(s); // Was cpy(char *s);
return *this;
}
operator char*(void) {
return ptr;
}
void cpy(char *s); // Don't forget ;
};
void my_string::cpy(char *s) {
delete [] ptr;
int n = strlen(s);
ptr = new char[n + 1];
strcpy(ptr, s);
}
int main()
{
my_string ms;
ms.cpy( "test" );
std::cout<< (char*)ms; // Never overloaded this before, but I figure this is how it should work.
// or the static_cast<char*>( ms ); equivalent.
return 0;
}
That defines the return type of a function. Replace it, for a moment, with 'int'. The function returns an integer variable. If you change it to int& it returns a reference to an integer. So my_string& returns a reference to an instance of a my_string object. That's what you want with an = operator. >> Also, why is there only one definition of cpy? I'm assuming that's not all the code there is. There probably should be. Write it yourself as a challenge.
__________________ I blag! |
| twomers is offline | |
| | #3 |
| Registered User Join Date: Oct 2008 Location: Leading lawn gnomes on the path to world domination! ;o)
Posts: 13
| Yeah, I was really only confused about Code: my_String& operator=(const my_string &object); Code: operator char*() {return ptr;}
Thank you for explaining my_string& for me, I really appreciate it! I'm still unsure how operator char* works, or what parts of the code are relevant to showing you where it is involved or not. So I copied down the entire code. I'm new so I'm unsure if all of this is even needed or not. If it isn't needed then I apologize for pasting the following monolith of code. Code: class String {
private:
char *ptr;
public:
String();
String(char *s);
String(const String &src);
~String();
String& operator=(const String &src)
{cpy(src.ptr); return *this;}
String& operator=(char *s)
{cpy(s); return *this;}
String operator+(char *s);
int operator==(const String &other);
operator char*() {return ptr;}
void cat(char *s);
void cpy(char *s);
};
int main() {
String a, b, c;
a = "I ";
b = "am ";
c = "so ";
String d = a + b + c + "very happy!\n";
cout << d;
return 0;
}
// ----------------------------------
// STRING CLASS FUNCTIONS
String::String() {
ptr = new char[1];
ptr[0] = '\0';
}
String::String(char *s) {
int n = strlen(s);
ptr = new char[n + 1];
strcpy(ptr, s);
}
String::String(const String &src) {
int n = strlen(src.ptr);
ptr = new char[n + 1];
strcpy(ptr, src.ptr);
}
String::~String() {
delete [] ptr;
}
int String:: operator==(const String &other) {
return (strcmp(ptr, other.ptr) == 0);
}
String String::operator+(char *s) {
String new_str(ptr);
new_str.cat(s);
return new_str;
}
// cpy -- Copy string function
//
void String::cpy(char *s) {
delete [] ptr;
int n = strlen(s);
ptr = new char[n + 1];
strcpy(ptr, s);
}
// cat -- Concatenate string function
//
void String::cat(char *s) {
// Allocate sufficient room for new string data.
int n = strlen(ptr) + strlen(s);
char *p1 = new char[n + 1];
// Copy data to this new memory block.
strcpy(p1, ptr);
strcat(p1, s);
// Release old memory block and update ptr.
delete [] ptr;
ptr = p1;
}
|
| Lawn Gnomusrex is offline | |
| | #4 |
| and the Hat of Guessing Join Date: Nov 2007
Posts: 8,740
| I still don't quite know what your question is, but we'll try this: operator char*() is the old-style C casting: just like you can cast an integer to float by (float)int_var, you can cast to char* as (char*)string_var. It's possible this may also be used for parameter-matching, i.e., if a function takes a char *, this can be used to convert your string into that parameter. (I don't know for sure if that's the mechanism; someone will be along soon to set me (and you) straight, but that would explain why you're talking about cout and <<.) If you're familiar with the STL std::string, then this operator char*() is doing basically the same job as .c_str() there. |
| tabstop is offline | |
| | #5 |
| Registered User Join Date: Oct 2008 Location: Leading lawn gnomes on the path to world domination! ;o)
Posts: 13
| If you remove this line: Code: operator char*() {return ptr;}
I'm just wondering how Code: operator char*() {return ptr;}
And I'm not at all familiar with STL libraries. sorry. |
| Lawn Gnomusrex is offline | |
| | #6 |
| and the Hat of Guessing Join Date: Nov 2007
Posts: 8,740
| Because cout knows how to print char*. It doesn't know how to print MyStrings, until either (1) you define how to convert MyStrings into char* -- this is what you did, or (2) you define << to work on MyStrings -- this is what most people do. |
| tabstop is offline | |
| | #7 |
| and the hat of sweating Join Date: Aug 2007 Location: Toronto, ON
Posts: 3,120
| operator char*() is a function that allows the object to be implicitly converted to a char* type. Those types of operators should be avoided though, since they can have bad interactions in your code. See Chapter 40. Avoid providing implicit conversions
__________________ "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008 |
| cpjust is offline | |
| | #8 | ||
| Registered User Join Date: Jan 2008
Posts: 575
| Quote:
Edit: Quote:
Soma | ||
| phantomotap is offline | |
| | #9 | |
| and the hat of sweating Join Date: Aug 2007 Location: Toronto, ON
Posts: 3,120
| Quote:
Code: str1 + "something"
__________________ "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008 | |
| cpjust is offline | |
| | #10 | ||
| Registered User Join Date: Jan 2008
Posts: 575
| Quote:
That was a spectacularly bad choice. If you have a string class that supports null-terminated 'const char *' strings then you should have 'string_type operator + (const string_type &, const char *)' anyway. Quote:
Soma | ||
| phantomotap is offline | |
| | #11 | |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,352
| Quote:
EDIT: Actually, I notice that cpjust linked to an online copy of a book that incorporates material from the GotW articles. The point is, you cannot "do the work to block otherwise logically illegal, or just silly, operations" if you have no control over the operations of the converted type, and this is certainly true of the built-in types, pointer types, and types provided by some library not under your control.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way Last edited by laserlight; 10-05-2008 at 01:02 AM. | |
| laserlight is online now | |
| | #12 | ||
| Registered User Join Date: Jan 2008
Posts: 575
| Quote:
No. That doesn't provide a good reason to avoid silent conversion and neither does the book equivalent. It only gives an excuse for lazy programmers to avoid them. Inheritance and multiple inheritance, especially the "Curiously Recurring Template Pattern", can interfere with overload resolution in the exact same ways. Actually, the implicit conversion provided on the constructor side of things, which 'std::string' provides, can yield similarly unexpected results. As for logically illegal or just silly operations--once again: write the code. <edit> Quote:
Ha! I always find fun stuff here. Who said to control the operations of the converted type? (I certainly didn't.) </edit> <edit> Oh, and just for fun: You can absolutely prevent every misuse referenced by "C++ Coding Standards" by doing the work, but the fun part is you don't even have to do the work but once: you can use the "Curiously Recurring Template Pattern" to provide an easy fix for any future classes. </edit> Soma Last edited by phantomotap; 10-05-2008 at 01:25 AM. | ||
| phantomotap is offline | |
| | #13 | |||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| Quote:
The world is full of programmers who seem to think that the & should bind to the name while it really should not (note: joke)! my_String& var, my_String & var and my_String &var mean the same thing. Quote:
But as cpjust mentioned, they should be avoided because they usually have nasty consequences. It's a shame, really.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
Last edited by Elysia; 10-05-2008 at 01:26 AM. | |||
| Elysia is offline | |
| | #14 | ||||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,352
| Quote:
Quote:
Quote:
Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | ||||
| laserlight is online now | |
| | #15 | |
| Registered User Join Date: Jan 2008
Posts: 575
| Quote:
This just gets better and better. Considering you posted the "Guru of the Week" link I assume you mean the 's1 = s2 - s3;' example. The relevant quote from the article: "The subtraction is meaningless and should be wrong. If string had an implicit conversion to const char*, however, this code would compile cleanly because the compiler would silently convert both strings to const char*'s and then subtract those pointers." The best part of this is: you are both wrong. First, it isn't a counter. Second, even with the implicit conversion it would not compile for a conforming compiler. Subtracting two pointers yields an integer type and 'std::string' has no such constructor. However, I think your point was probably: how do I prevent the silent conversion to 'const char *' from causing problems when used with the subtraction operator. The answer is the same for every operator associated with the intended conversion: provide the operator and either prevent successful compilation or crash with a well-formed error during execution. Soma | |
| phantomotap is offline | |
![]() |
| Tags |
| class, classes, pointers, references, strings |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Can anybody show me why this works?? | tzuch | C Programming | 2 | 03-29-2008 09:03 AM |
| Understanding formulas, shapes, algorithms etc | hardi | General Discussions | 26 | 04-16-2007 01:23 PM |
| Works outside of the loop, not within | Decrypt | C++ Programming | 5 | 08-05-2006 12:22 AM |
| understanding recursive functions | houler | C Programming | 7 | 12-09-2004 12:56 PM |
| Understanding Headers and Inclusions | jdm | C++ Programming | 11 | 04-21-2004 10:11 PM |