assignment operator

This is a discussion on assignment operator within the C++ Programming forums, part of the General Programming Boards category; Hi need to implement assignment operator for class TFoo below such that the code in main will operate as indicated. ...

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    28

    assignment operator

    Hi need to implement assignment operator for class TFoo below such that the code in main will operate as indicated.

    I have these assumptions:
    a) the constructor/destructor code for Foo has been omitted; I am to assume that it is properly implemented
    b) the 'i_myData' member is correctly assigned and destroyed in the omitted code

    I have these restrictions:
    I may add methods to the TFoo class, but I should not modify existing methods
    I have to ensure that memory/resources are cleaned-up

    I'd appreciate some help,
    Thanks.

    Code:
    class Data { 
        // implemented elsewhere
    };
    
    class TFoo {
      int& i_Value;
      Data* i_myData; // initialized in constructor
      
    public:
      TFoo(int& v) : i_Value(v) { 
          // implemented elsewhere
      }
      ~TFoo() {
          // implemented elsewhere
      }
      
      void Increment() { ++i_Value; }
      
      //tried this but not correct!
      TFoo & operator= (const TFoo & other) {
        if (this != &other)
        {
          i_Value = other.i_Value; 
    
        }
    
        return *this;
      }  
    };
    
    
    int main() 
    {
      int i = 0;
      int j = 1;
      int k = 3;
      TFoo foo1(i);
      TFoo foo2(j);
      foo1.Increment();
      foo2.Increment();
      
      printf("%d,%d,%d\n", i, j, k); // displays "1,2,3"
      
      foo1 = foo2;
      foo2 = k;
      foo1.Increment();
      foo2.Increment();
      
      printf("%d,%d,%d\n", i, j, k); // displays "1,3,4"
      
      return 0;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,165
    Since i_Value is a reference member, I am inclined to disable the copy assignment operator by declaring it private and not implementing it, but it looks like that is not an option for you.

    You could still use the copy and swap idiom: implement a swap member function that swaps the i_myData member pointers, then implement the copy assignment operator using the copy constructor, swap member function and destructor.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It's impossible to reseat a reference.

    If you want to produce that output, you'll need to replace the reference member with a pointer member.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Jun 2006
    Posts
    28
    thanks for the ideas, but changing i_Value to be a pointer, is not an option.

  5. #5
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by anon View Post
    It's impossible to reseat a reference.

    If you want to produce that output, you'll need to replace the reference member with a pointer member.
    Never "really" used a reference type variable, but can't you just change the object it references to like:
    Code:
    int* tmp = &i_Value;
    *tmp = 100;
    ?

    Quote Originally Posted by laserlight View Post
    Since i_Value is a reference member, I am inclined to disable the copy assignment operator by declaring it private and not implementing it, but it looks like that is not an option for you.

    You could still use the copy and swap idiom: implement a swap member function that swaps the i_myData member pointers, then implement the copy assignment operator using the copy constructor, swap member function and destructor.
    Huh? (an example will be appreciated)

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,308
    In a class I saw recently that contained a reference member, the assignment operator simply asserted that both references referred to the same object, and then assigned the remaining members. Perhaps you can do that?

    You really need to know how the i_myData variable gets its value to complete this though, otherwise there is no way to know if whatever you implement is correct. It may be malloc'd new'd, new[]'d, be allocated from some special memory pool, just point to a global object, point to one of its own members, or a hundred other possibilites.
    If this is all you are given then there is pretty much no right or wrong answer.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,165
    Quote Originally Posted by C_ntua
    Never "really" used a reference type variable, but can't you just change the object it references to like:
    Code:
    int* tmp = &i_Value;
    *tmp = 100;
    ?
    What that code snippet does is this: get the address of what i_Value refers to, e.g., i and store it in tmp. Set what tmp points to to 100, e.g., i is set to 100. The reference named i_Value still refers to i.

    Quote Originally Posted by C_ntua
    Huh? (an example will be appreciated)
    Basically, this:
    Code:
    class TFoo
    {
    public:
        // ...
    
    private:
        // ...
    
        void operator=(const TFoo& other);
    };
    or this:
    Code:
    class TFoo
    {
    public:
        // ...
    
        TFoo& operator=(const TFoo& other)
        {
            TFoo temp(*this);
            swap(temp);
            return *this;
        }
    
        void swap(TFoo& other)
        {
            using std::swap;
            swap(i_myData, other.i_myData);
        }
    
        // ...
    };
    Of course, looking carefully at the desired sample output, I believe that what acosgaya wants to do cannot actually be done within the constraints for the reason that anon stated: references cannot be rebound.

    Quote Originally Posted by iMalc
    In a class I saw recently that contained a reference member, the assignment operator simply asserted that both references referred to the same object, and then assigned the remaining members. Perhaps you can do that?
    It is an option, but then the sample code would then cause the assertion to fail since foo1.i_Value and foo2.i_Value do not refer to the same object. My suggestion would cause a compile error in the first case and wrong output in the second case, but I cannot see a way around the wrong output without changing the reference to a pointer.
    Last edited by laserlight; 02-19-2011 at 01:32 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,531
    There is actually a technique, but it is strongly discouraged.
    Code:
    TFoo & operator= (TFoo & other) {
        if (this != &other)
        {
              this->~TFoo();
              new (this) TFoo(other.i_Value);
        }
    
        return *this;
      }
    Generally, if such techniques are required, they are a warning sign indicating a badly broken class design.

    This technique means that TFoo should never be used as a base class. Effectively, the assignment operator of derived classes (whether written by programmer, or compiler generated) will slice the object in different ways, depending on how users of the class do things.

    More directly, since the constructor of TFoo takes a non-const reference to int, that it is necessary to remove the const qualifier from the "other" argument of the assignment operator. In other words, an assignment operation is allowed to modify the right hand side operand - in itself, this is (almost invariably) a positive indicator of a broken class design.

    If the right hand side must be const, the implementation can be done as.
    Code:
    TFoo & operator= (const TFoo & other) {
        if (this != &other)
        {
              this->~TFoo();
              new (this) TFoo((const_cast<TFoo &>(other)).i_Value);
        }
    
        return *this;
      }
    which is really just a sleight of hand: the specification of the assignment operator promises not to change other, but the implementation of the function does not honour that promise. Another indicator of a broken design.....
    Last edited by grumpy; 02-19-2011 at 04:15 PM. Reason: Fixed typo
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Jun 2006
    Posts
    28
    thanks grumpy, I understand the broken design point; do you care to explain what is really going on inside this technique

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    In the first, you are essentially destroying your object and re-creating it while your object is doing some work. grumpy also mentions other problems, and the problem is basically that new will always have the same type as the class it is in, whether or not that is a base class. So if a derived class uses that class as a base class, the object will destroy itself and create a new instance of the base class, and not the derived class, causing all sorts of problems.

    As for the second, there is the problem of the assignment operator modifying the right-hand side. When you say x = y, then you expect x to equal y, but you also expect y to be unmodified. If y is then modified, it's usually a sign of a broken design. Therefore, the assignment operator typically takes a const type.

    The last example is just as broken in that it works essentially the same. Only instead of taking a non-const type, it simply casts away the constness, which is even worse. It would allow code that would otherwise not compile to actually compile, causing all sorts of weirdness at runtime.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copy Constructors and Assignment Operator overloading.
    By leeor_net in forum C++ Programming
    Replies: 1
    Last Post: 11-09-2009, 10:26 PM
  2. Assignment operator and iterators
    By maxsthekat in forum C++ Programming
    Replies: 3
    Last Post: 09-11-2009, 01:19 PM
  3. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 07:22 AM
  4. Replies: 1
    Last Post: 10-27-2006, 02:21 PM
  5. containers/ assignment operator
    By Kirdra in forum C++ Programming
    Replies: 2
    Last Post: 10-08-2004, 11:17 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21