dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 32

Thread: Why'd I get a compiler error?

  1. #1
    Join Date
    Aug 2000
    Posts
    1,471

    Why'd I get a compiler error?

    My code is shown in the following, I tried to compile it using VS2008, but got a compiler error C2678: binary '+' : no operator found which takes a left-hand operand of type 'const char [7]' (or there is no acceptable conversion). I couldn't figure out what is wrong with my code. Thanks for your inputs.

    Code:
    class MyString
    {
    public:
    	MyString& operator=(const MyString& rhs)
    	{
    		if(this != &rhs)			
    			strcpy_s(m_str,strlen(rhs.m_str)+1, rhs.m_str);
    
    		return *this;
    	}
    
    	MyString(const MyString& rhs)
    	{
    		m_str = new char[strlen(rhs.m_str)+1];
    		strcpy_s(m_str,strlen(rhs.m_str)+1, rhs.m_str);
    	}
    
    	MyString(const char* str) 
    	{
    		m_str = new char[strlen(str)+1];
    		strcpy_s(m_str,strlen(str)+1, str);
    	}
    
    	MyString()
    	{
    		m_str = new char[1024];
    	}
    
    	~MyString()
    	{
    		delete[] m_str;
    	}
    
    	operator const char *() const
    	{
    		return m_str;
    	}
    
    	friend MyString operator+(MyString& a, const MyString& b);
                         friend ostream& operator<<(ostream& os, const MyString& str);
    	
    private:
    	char* m_str;
    };
    
    
    MyString operator+(MyString& a, const MyString& b)
    {
    	int nLen1 = strlen(a.m_str);
    	int nLen2 = strlen(b.m_str);
    
    	char* tem = new char[nLen1+1];
    	strcpy_s(tem, nLen1+1, a.m_str);
    
    	delete[] a.m_str;
    
    	a.m_str = new char[nLen1+nLen2+1];
    	strcpy_s(a.m_str, strlen(tem)+1, tem);
    
    	strcat_s(a.m_str, nLen1+nLen2+1, b.m_str);
    
    	delete[] tem;
    	return a.m_str;
    }
    
    ostream& operator<<(ostream& os, const MyString& str)
    {
    	os<<str.m_str;
    	return os;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MyString s1("Hi");	
                        MyString s2;
    
                       s2 = "there " + s1;
    	return 0;
    }

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,173

    Re: Why'd I get a compiler error?

    This error is to tell you that you shouldn't be writing your own string class.

  3. #3
    Join Date
    Feb 2002
    Posts
    4,640

    Re: Why'd I get a compiler error?

    Well, I don't see an override for adding a string to a character array. So, the error is correct.

    Viggy

  4. #4
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Why'd I get a compiler error?

    But if I use s2 = s1 + "there ", it compiles fine, which means a character array is implicitly converted to a string and which also means your defense is wrong. My question is that why such conversion failed when a character array is on the left hand of operator +? The operator + doesn't look symetrical. Why? Thanks for your inputs.
    Quote Originally Posted by MrViggy View Post
    Well, I don't see an override for adding a string to a character array. So, the error is correct.

    Viggy

  5. #5
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Why'd I get a compiler error?

    this:
    Code:
    s2 = "there " + s1;
    will be evaluated by trying to perform: "there " + s1 , then assign the results to s2. const char [7] is a POD type and has no overload for type "string".

  6. #6
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Why'd I get a compiler error?

    But according to your explaination, what do you think s2 = s1 + "there "? Here "there " is still a POD type. But it unfortunately compiles fine. Do you know the difference? Thanks for your inputs.
    Quote Originally Posted by hoxsiew View Post
    this:
    Code:
    s2 = "there " + s1;
    will be evaluated by trying to perform: "there " + s1 , then assign the results to s2. const char [7] is a POD type and has no overload for type "string".

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Why'd I get a compiler error?

    Yes, but "There" can be implicitly converted to a MyString to match the signature of your operator+. Therefore it compiles.

  8. #8
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Why'd I get a compiler error?

    My question is actually why s2 = "there " + s1 does NOT compile whereas
    s2 = s1 + "there " does compile. Thanks for your inputs.
    Quote Originally Posted by Lindley View Post
    Yes, but "There" can be implicitly converted to a MyString to match the signature of your operator+. Therefore it compiles.

  9. #9
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Why'd I get a compiler error?

    I don't know any clearer way of explaining it. s1 is a class with a + operator, the class decides what to do with the rvalue. "there " is NOT a class. It has no + operator. With no + operator, the compiler applies the default POD operation which is NOT appropriate for a const char[7] datatype.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Why'd I get a compiler error?

    Quote Originally Posted by dullboy View Post
    My question is actually why s2 = "there " + s1 does NOT compile
    First, I'll shorten the code:
    Code:
    class MyString
    {
    public:
    	MyString& operator=(const MyString& rhs);
    	MyString(const MyString& rhs);
    	MyString(const char* str);
    	MyString();
    	~MyString();
    	operator const char *() const;
    	friend MyString operator+(MyString& a, const MyString& b);
    	
    private:
    	char* m_str;
    };
    
    
    int main()
    {
    	MyString s1("Hi");	
            MyString s2;
            s2 = "there " + s1;
    	return 0;
    }
    This is basically the entire code with the error recreated. Change the first parameter of your operator + to a const reference, and you will see that the code will now compile.
    Code:
    MyString operator+(const MyString& a, const MyString& b)
    Why wasn't the first parameter const to begin with? You're not really supposed to be changing the value of the first or second argument.

    Similarly, if you changed the second parameter to non-const, you will see that your first example of

    s1 + "somestring"

    will no longer compile. So const plays a role in why things will or will not compile.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Jun 2008
    Posts
    592

    Re: Why'd I get a compiler error?

    I already gave him the answer in this thread http://www.codeguru.com/forum/showthread.php?t=491500 on post http://www.codeguru.com/forum/showpo...1&postcount=11

    This thread is just another repeat of the previous attempt of him not knowing what he is doing and thinking he is right. I don't know why he doesn't listen
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  12. #12
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Why'd I get a compiler error?

    Thanks for your explaination! Here is my revised code. But obviously there is another problem. In the implementation of operator+, there is memory leak. How should I do to avoid memory leak? Thanks for your inputs.
    Code:
    class MyString
    {
    public:
    	MyString& operator=(const MyString& rhs)
    	{
    		if(this != &rhs)			
    			strcpy_s(m_str,strlen(rhs.m_str)+1, rhs.m_str);
    
    		return *this;
    	}
    
    	MyString(const MyString& rhs)
    	{
    		m_str = new char[strlen(rhs.m_str)+1];
    		strcpy_s(m_str,strlen(rhs.m_str)+1, rhs.m_str);
    	}
    
    	MyString(const char* str) 
    	{
    		m_str = new char[strlen(str)+1];
    		strcpy_s(m_str,strlen(str)+1, str);
    	}
    
    	MyString()
    	{
    		m_str = new char[1024];
    	}
    
    	~MyString()
    	{
    		delete[] m_str;
    	}
    
    	operator const char *() const
    	{
    		return m_str;
    	}
    
    	friend MyString operator+(const MyString& a, const MyString& b);
                         friend ostream& operator<<(ostream& os, const MyString& str);
    	
    private:
    	char* m_str;
    };
    
    
    MyString operator+(const MyString& a, const MyString& b)
    {
                        int nLen1 = strlen(a.m_str);
    	int nLen2 = strlen(b.m_str);
    
    	char* tem = new char[nLen1+nLen2+1];
    	strcpy_s(tem, nLen1+1, a.m_str);
    
    	strcat_s(tem, nLen1+nLen2+1, b.m_str);
    	
    	return tem;
    }
    
    ostream& operator<<(ostream& os, const MyString& str)
    {
    	os<<str.m_str;
    	return os;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MyString s1("Hi");	
                        MyString s2;
    
                       s2 = "there " + s1;
    	return 0;
    }
    Quote Originally Posted by Paul McKenzie View Post
    First, I'll shorten the code:
    Code:
    class MyString
    {
    public:
    	MyString& operator=(const MyString& rhs);
    	MyString(const MyString& rhs);
    	MyString(const char* str);
    	MyString();
    	~MyString();
    	operator const char *() const;
    	friend MyString operator+(MyString& a, const MyString& b);
    	
    private:
    	char* m_str;
    };
    
    
    int main()
    {
    	MyString s1("Hi");	
            MyString s2;
            s2 = "there " + s1;
    	return 0;
    }
    This is basically the entire code with the error recreated. Change the first parameter of your operator + to a const reference, and you will see that the code will now compile.
    Code:
    MyString operator+(const MyString& a, const MyString& b)
    Why wasn't the first parameter const to begin with? You're not really supposed to be changing the value of the first or second argument.

    Similarly, if you changed the second parameter to non-const, you will see that your first example of

    s1 + "somestring"

    will no longer compile. So const plays a role in why things will or will not compile.

    Regards,

    Paul McKenzie

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,173

    Re: Why'd I get a compiler error?

    Quote Originally Posted by dullboy View Post
    Thanks for your explaination! Here is my revised code. But obviously there is another problem. In the implementation of operator+, there is memory leak. How should I do to avoid memory leak? Thanks for your inputs.
    Preventing memory leaks is simple. Anytime you allocated memory with new (or new[]) you need to clean it up with delete (or delete[]).

    That's it in a nutshell - no magic here.

    That also means that anytime you allocate memory to a pointer, you make sure that if the pointer already contains memory, you clean that up before allocating new memory.

    Generally you'll want to have a CleanUp( ) method that you can call before you allocate and then again in the dtor.

  14. #14
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Why'd I get a compiler error?

    I understand anytime I allocated memory with new (or new[]), I need to clean it up with delete (or delete[]). But if you take a look at the operator+, I allocated memory for char* tem, but I need to return it. How'd I return it and at the mean time I am able to deallocate its memory? Thanks for your inputs.
    Quote Originally Posted by Arjay View Post
    Preventing memory leaks is simple. Anytime you allocated memory with new (or new[]) you need to clean it up with delete (or delete[]).

    That's it in a nutshell - no magic here.

    That also means that anytime you allocate memory to a pointer, you make sure that if the pointer already contains memory, you clean that up before allocating new memory.

    Generally you'll want to have a CleanUp( ) method that you can call before you allocate and then again in the dtor.

  15. #15
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Why'd I get a compiler error?

    Given your current methods, the obvious way to avoid the memory leak would be to construct a MyString with tem, and then delete tem, and then return the MyString by value.

    However, your operator= is incorrect. You'll need to fix it. Right now, it makes no attempt to verify that there is enough space in the destination string to copy the rhs string. In fact, your MyString class does not even store the amount of space allocated. While its possible to just reallocate every time the contents of the string changes, this is highly inefficient. You should add a capacity field.
    Last edited by Lindley; January 29th, 2010 at 11:55 AM.

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)