Thread: my short sightedness........ help....

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    91

    my short sightedness........ help....

    Hi !

    Just working to learn some C++ and even though this program worked I failed to understand the underlying concept.......


    This is snippet from a program ..... and this is an overloaded "+" operator.... CmyString is a class with two members a string m_pstr and an integer length (length of the string)....pretty simple layout....

    my first question why is the function parameter "const CmyString& b" and not just "const CmyString b"


    Code:
    CmyString CmyString::operator+(const CmyString& b)
    {
    	CmyString temp;
    	temp.length = this->length + b.length;
    	delete [] temp.m_pstr;
    	temp.m_pstr = new char [temp.length + 1];
    	strcpy(temp.m_pstr, this->m_pstr);
    	strcat(temp.m_pstr, b.m_pstr);
    	
    	return temp;
    }
    I also had a overlaoded "=" operator in the program

    Code:
    CmyString& CmyString::operator=(const CmyString& b)
    {
    	if(this != &b)
    	{
    		length= b.length;
    		delete [] m_pstr;
    		m_pstr = new char[strlen(b.m_pstr) + 1];
    		strcpy(m_pstr, b.m_pstr);
    	}
    
    	return *this;
    }
    So lets say there are three objects :

    Cmystring a;
    Cmystring b;
    Cmystring c;

    A statement like

    c = a+b;

    would execute from left to right so would be

    c.operator=(a.operator+(b));

    but the object returned by a.operator+(b) will be destroyed... or will it not be ..... ????? I think I got confused in the concepts or refrence and pointers somewhere ......

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> why is the function parameter "const CmyString& b" and not just "const CmyString b"

    The & signifies a reference parameter. You can read up on references in C++. Basically, instead of a copy of the string being made and passed to the function, a reference to the existing string is passed. This saves time by not copying the contents of the string class. It is similar to passing a pointer.

    >> but the object returned by a.operator+(b) will be destroyed... or will it not be ..... ?????

    Yes, it will be destroyed. It is a temporary variable that holds a + b. It sticks around long enough to be passed to c.operator= so that c can get the new value, and then the temporary is destroyed. It is possible that the temporary object might be optimized away by the compiler, but from a theoretical standpoint you can assume it is there.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    my first question why is the function parameter "const CmyString& b" and not just "const CmyString b"
    When the argument you send to the function is CmyString (vs. CmyString&), a copy of the object is made for the function. The function then operates on the copy, and any changes it makes to the copy are not reflected in the original object that was sent to the function. When the function ends, the copy of the object is destroyed.

    When the argument you send to the function is CmyString&, then only the address of where the object is in memory is sent to the function. Once again, a copy of the argument is made for the function, but this time what is being copied for the function is an address. However, an address and a copy of an address both refer to the same object. Therefore, when you make changes to the object inside the function using a copy of an address, the changes are made directly to the original object.

    The bottom line is that making changes to an object whether it's through an address or a copy of an address both yield the same result: the original(and only object in existence) is changed. On the other hand, when an object is copied for a function, two objects exist: the original and the copy, and the function operates on the copy, which means the original object is unaffected.

    So, using that little & symbol has two effects:

    1) It's more efficient. It causes only the object's address in memory to be copied for the function. Copying just an object's address, which you can think of as an integer, is much quicker than copying the whole object, which may have many members.

    2) It allows you to change the original object. When the function makes changes to the object, the changes are made directly to the original object that was sent to the function.

    In your case, you have additionally declared the function parameter "const", which prevents the function from changing the object, nullifying effect (2). That is a good practice when your function doesn't need to change the object. As a result, you get only one of the effects of using the "&" symbol: efficiency.

    but the object returned by a.operator+(b) will be destroyed... or will it not be ..... ?????
    [deleted because it was incorrect]
    Last edited by 7stud; 02-02-2006 at 07:10 PM.

  4. #4
    Registered User
    Join Date
    Feb 2005
    Posts
    91
    hi !

    thanks guys ..... I guess now I can throw out the real deal ......

    I get all what you said that the object is destroyed but what if I don't want that

    this is the main function that i wrote which doesn't work:

    Code:
    int main()
    {
    	CmyString a ("my first");
    	CmyString b ("your first");
    	CmyString c ("our first");
    	a.printstr();
    	b.printstr();
    	c.printstr();
    	CmyString d;
    	d = (a+b)+c;
    	d.printstr();
                    return 0;
    }
    since the object is destroyed ..... I guess.....

    in the operator overload for "=" the function declaration is :

    Code:
    CmyString& CmyString::operator=(const CmyString& b)
    {
    	if(this != &b)
    	{
    		length= b.length;
    		delete [] m_pstr;
    		m_pstr = new char[strlen(b.m_pstr) + 1];
    		strcpy(m_pstr, b.m_pstr);
    	}
    
    	return *this;
    }
    the return type "CmyString&" makes sure that we can execute statements like

    (c = a) = b;

    since the object on the left stays since its a refrence.......

    Can I do something like that for the "+" operator

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    the return type "CmyString&" makes sure that we can execute statements like
    The question is whether you need to return anything from operator=(). If you write this:

    a = b;

    operator=() doesn't need to return anything. It can just set the values of a equal to the values of b. However, if you want to be able to write statements like this for your class:

    a = b = c;

    then your operator=() has to return something. A statement like that is executed from right to left, like this:

    a = (b = c);

    If your operator=() doesn't return anything, then you will get:

    a = (void);

    which is not what you want. The reason you make the return value of operator=() a reference is for efficiency. When you return a reference, the whole object doesn't have to be copied--only its address in memory is copied and returned.

    All the operator overload functions follow specific formats. You can look up any of them and get the proper format. As for operator+(), you will want to write statements like this:

    a = b + c;

    So, operator+() needs to return a new object that results from (b + c). You could just add c to b and return b, but then b would be altered. The normal operation is to leave b and c unchanged. Since you are going to be creating a new object in your operator+() function, you do not want to return a reference to that object. When a function ends, the variable names declared inside it are destroyed. So, if you return a reference to the object, it will refer to something that doesn't exist.

    As a result, you want to pass by value in your return statement. That way, a copy of the object you declared in your operator+() function will be returned. The original will get destroyed when the function ends, but that won't affect the copy. You pass by value in your return statement by omitting the & symbol.
    Last edited by 7stud; 02-03-2006 at 01:08 AM.

  6. #6
    Registered User
    Join Date
    Feb 2005
    Posts
    91
    thanks for the explantion 7stud .......

    but my problem is that I want to execure something like "c = a + b + c" or "c = "(a+b) + c"

    and non of them seem to be working how can I change that.......

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Post the declaration of your CmyString class as well as your operator+() function.

  8. #8
    Registered User
    Join Date
    Feb 2005
    Posts
    91
    Here are the files you will need, the name of the file is commented on top:

    Code:
    // myString.h: interface for the CmyString class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(AFX_MYSTRING_H__60C5F526_B091_4FE3_B074_23E7BF46A940__INCLUDED_)
    #define AFX_MYSTRING_H__60C5F526_B091_4FE3_B074_23E7BF46A940__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    class CmyString  
    {
    public:
    	CmyString& operator+=(const CmyString& b);
    	CmyString operator+(const CmyString& b);
    	CmyString& operator=(const CmyString& b);
    	CmyString(char* pstr ="Default String");
    	CmyString(const CmyString& temp);
    	virtual ~CmyString();
    	void printstr();
    	char* getString() const { return m_pstr; };
    
    
    
    private:
    	int length;
    	char* m_pstr;
    };
    
    #endif // !defined(AFX_MYSTRING_H__60C5F526_B091_4FE3_B074_23E7BF46A940__INCLUDED_)


    Code:
    // myString.cpp: implementation of the CmyString class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include "myString.h"
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    
    CmyString::CmyString(char* pstr)
    {
    	m_pstr = new char [strlen(pstr) + 1];
    	strcpy(m_pstr, pstr);
    	length = strlen(m_pstr);
    }
    
    CmyString::CmyString(const CmyString& temp)
    {
    	m_pstr = new char [strlen(temp.m_pstr) + 1];
    	strcpy(m_pstr, temp.m_pstr);
    }
    
    CmyString::~CmyString()
    {
    	delete [] m_pstr;
    	m_pstr = NULL;
    }
    
    void CmyString::printstr()
    {
    	cout << m_pstr << endl;
    }
    
    
    CmyString& CmyString::operator=(const CmyString& b)
    {
    	if(this != &b)
    	{
    		length= b.length;
    		delete [] m_pstr;
    		m_pstr = new char[strlen(b.m_pstr) + 1];
    		strcpy(m_pstr, b.m_pstr);
    	}
    
    	return *this;
    }
    
    CmyString CmyString::operator+(const CmyString& b)
    {
    	CmyString temp;
    	temp.length = this->length + b.length;
    	delete [] temp.m_pstr;
    	temp.m_pstr = new char [temp.length + 1];
    	strcpy(temp.m_pstr, this->m_pstr);
    	strcat(temp.m_pstr, b.m_pstr);
    	
    	return temp;
    }
    
    CmyString& CmyString::operator+=(const CmyString& b)
    {
    	this->length += b.length;
    	char* tempString = new char [this->length + 1];
    	strcpy(tempString, this->m_pstr);
    	delete[] this->m_pstr;
    	this->m_pstr = new char [this->length + 1];
    	strcpy(this->m_pstr, tempString);
    	strcat(this->m_pstr, b.m_pstr);
    	
    	return *this;
    }

    Code:
    // string_main.CPP
    // A sample string problem
    #include <iostream>
    #include "myString.h"
    using namespace std;
    
    int main()
    {
    	CmyString a ("my first");
    	CmyString b ("your first");
    	CmyString c ("our first");
    	a.printstr();
    	b.printstr();
    	c.printstr();
    	CmyString d;
    	d = a+b+c;
    	d.printstr();
    	//c += a;
    	//c.printstr();
    
       return 0;
    }
    Last edited by gemini_shooter; 02-03-2006 at 03:26 AM.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    The problem is the copy constructor
    Code:
    CmyString::CmyString(const CmyString& temp)
    {
    	m_pstr = new char [strlen(temp.m_pstr) + 1];
    	strcpy(m_pstr, temp.m_pstr);
    	length = temp.length; 
    }
    Kurt

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Your copy constructor is faulty.

  11. #11
    Registered User
    Join Date
    Feb 2005
    Posts
    91
    gr888t job thanks...... as the heading suggests.... I ran into some more code which is also related to overloading......


    Code:
    bool Name:: operator<(const Name& name) const
    {
       int result = strcmp(pSurname, name.pSurname);
       if(result < 0)
           return true;
       if(result == 0 && strcmp(pFirstname, name.pFirstname) < 0)
           return true;
       else
           return false;
    }
    
    bool Name::operator>(const Name& name) const
    {
        return name > *this;
    }
    I didn't really understand how is the second function working ......

    I guess I know that it is using the first overloaded operator...... but how.......

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> return name > *this;

    If you change it to return name < *this;, then it will be correct. Basically, a > b if and only if b < a. So it switches the arguments and uses the operator< to do the work. This is good practice since a change to the implementation of the ordering of the class will only need to be made in one place instead of two.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Accessing Structures Inside Structures
    By Mellowz in forum C Programming
    Replies: 1
    Last Post: 01-13-2008, 03:55 AM
  2. Help calling function is asm
    By brietje698 in forum C++ Programming
    Replies: 24
    Last Post: 12-06-2007, 04:48 PM
  3. Say what? - Weird error.
    By Blackroot in forum C++ Programming
    Replies: 6
    Last Post: 08-15-2006, 11:54 PM
  4. Help with mult-dim arrays and pointers to them
    By skybolt_1 in forum C Programming
    Replies: 11
    Last Post: 05-02-2003, 11:47 AM
  5. Color Variety
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 10-23-2002, 09:17 AM