1

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
         ...
   };

My Questions:

  1. Why "hello" does not get printed?
  2. Why 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

1
  • You need to look up the rule of three (or is four). Anyway a correct assignment operator and copy constructor are needed (copy constructor is missing and assignment operator declaration is not what I would call standard (And the implementation is buggy (of by one error in len))). While you are at it look up the copy and swap idium. Commented Sep 3, 2010 at 23:27

5 Answers 5

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

@pm100 a default one is generated
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?
1

Link error is that you have not defined

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

due to the line

cout << this << endl;

2 Comments

interesting that it compiles but fails to link. I would have thought it would fail to compile
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.
0

I think it should be

operator=(const myString &orig)

Comments

0
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 ?).

2 Comments

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!)
0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.