views:

95

answers:

5

Hi,

I've created a class myString and I'm trying to run the following code:

class myString{
    char* str;
    int len;

public:
    myString(char* str1 = " "){
        len = strlen(str1);
        str = new char[len+1];
        strcpy(str, str1);
    };

    int getLen() const {
        return len;
    };

    char* getString() const {
        return str;
    };

    ~myString(){
        delete[] str;
    };

    myString& operator=(myString& orig){
        cout << "hello";
        if (str == NULL){
            delete[] str;
        };
        str = new char[orig.getLen()];
        strcpy(str, orig.getString());
        cout << this << endl;
        return *this;
    };

    ...
};



int main(){


    myString s("bla");
    myString k("dingo");
        myString g = s;
        // s=k;  //When this line is commented I get a linking error
         ...
   };

could u please tell me: 1. the "hello" doesn't get printed - 2. the line s=k causes a linker error:

This is the error: LINK : c:\users\perry\documents\visual studio 2010\Projects\inheritance\Debug\inheritance.exe not found or not built by the last incremental link; performing full link 1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class myString *)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@PAVmyString@@@Z) referenced in function "public: class myString & __thiscall myString::operator=(class myString &)" (??4myString@@QAEAAV0@AAV0@@Z) 1>c:\users\perry\documents\visual studio 2010\Projects\inheritance\Debug\inheritance.exe : fatal error LNK1120: 1 unresolved externals

Thanks, Li

+2  A: 

For the following, you need a copy constructor. It does not use the assignment operator function.

myString g = s;

Edit

For the linker error - I can't help you with that. Rather than guessing at what operator<< that line calls, I will just give up on this because you haven't provided the code. In normal C++ code, there is no way that a simple cout << this; would cause a linker error. cout has an operator that accepts a void const* for this. You have declared an operator somewhere that provides a better match but did not define it.

Johannes Schaub - litb
i wonder how it compiled?
pm100
@pm100 a default one is generated
Samuel_xL
Thanks. I will add the copy constructor. Any idea about the linking error?
so what does happen when g = s executes? and why is s=k treated differently by the compiler?
Gabriel
@lazygoldenpanda see my answer about the linking error
Samuel_xL
A: 

I think it should be

operator=(const myString &orig)
pm100
I've added the "const" but I still get the linking error :(
A: 
myString g = s;

This doesn't call operator=, but the copy constructor. Since you have not defined any copy constructor, a default one is generated, copying all fields. But you're holding pointers, you don't want that to happen ! That's why you need a copy constructor.

About the linking error:

cout << this << endl;

Here, you try to use operator<< with this. The type of this is myString*, for which this operator is not defined. If you want to print the value of the this pointer, you can convert it:

cout << (void*) this << endl;



 if (str == NULL){
                delete[] str;
            };

You want if (str != NULL) here (typo ?).

Samuel_xL
right,thanks :)
Woohoo!!! Thanks, that (void*) saved my night. thank you very much. For some reason when I see those linking errors I freak out. I have to start reading them more carefully. Thanks!!!
By the way, the NULL check is unnecessary. It's well-defined and legal to `delete NULL` or `delete[] NULL`. Nothing happens. And also you don't need semi-colons at the end of function blocks or conditional (if) blocks -- only after class and struct definitions (and statements, of course!)
Tyler McHenry
+1  A: 

Link error is that you have not defined

operator<<(class std::basic_ostream< >  &,class myString *)

due to the line

cout << this << endl;
Greg Domjan
interesting that it compiles but fails to link. I would have thought it would fail to compile
pm100
not sure if it is just MSVC, but it often takes the first use of a method if it is unknown as the default definition which can hide the compilation issue of using something that is undefined.
Greg Domjan
A: 

In the first place, myString g = s; is the initialization of a new myString, and that's done with the copy constructor (which is automatically provided because you didn't write one).

The link error is because of the line cout << this << endl;, since you haven't told the system how to print this, and it apparently can't come up with a way.

In C++, there's the Rule of Three: if you write a copy constructor, assignment operator, or destructor, you probably need to write all three. (The exception is writing a virtual destructor for a base class.) Typically, then, your class manages some resource (str in your case), and you need to handle it in all three cases.

Also, use const when you can. You can pass a non-const variable into a const reference, but not vice versa.

Your destructor is fine. Your assignment operator should have the signature myString & operator=(const &myString), and your copy constructor should have the signature myString::myString(const &myString).

David Thornley