views:

252

answers:

3

Hello,

I have an abstract virtual base class Foo from which I derive many other classes that differ in small ways. I have a factory that creates the derived classes and returns Foo*. One of my bigger problems is in my operator overloads, I need to make sure that the DFoo does not get operated on by DFoo1 (not shown). I have currently handled this with checking if a cast fails, but I'm pretty unhappy with that approach. I have to use the base implementation, because I only can return the base class from the factory. If this is the best way to do it, that's fine, I just want to make sure that this makes sense and that there isn't a pattern I'm missing. Any suggestions about how to handle this sort of thing are very much appreciated.

 class Foo
 {
    public:
          Foo(int x){...};
          Bar m_bar;
          virtual Foo& operator=(const Foo& f)
          {
             m_bar = f.m_bar
          }
 }

Now, my derived class

class DFoo : public Foo
{
     DFoo(int x, int y):Foo(int x) {...}
     FooBar m_foobar;

     Foo& operator=(const Foo& rhs)
     {
        if(this != &rhs)
        {

              Foo::operator=(rhs);
              DFoo temp = static_cast<DFoo>(rhs);

              if(temp != NULL)
              {
                m_foobar = static_cast<DFoo>(rhs).m_foobar;
              }
              else
                 throw exception(ex);
        }
     }
}
+1  A: 

You are probably looking for boost::noncopyable.

Nikolai N Fetissov
yes, that would make life much easier. thanks
Steve
A: 

The smartest thing to do in this situation is to declare assignment operators and copy constructors but not define them. Then if somewhere in your code someone tries to make a copy it will generate a linker error. This is essentially the effect that boost::nocopyable has except that you're not bringing in an external library for such a simple and trivial task.

Edit: Also if you make the constructor and operator private you will get a compiler error.

Chris
A: 

You should never do this:

 class DFoo
 {
     Foo& operator=(const Foo& rhs) ;
 };

Unless you explicitly want to support the assignment of a base class to a derived type (unlikely).
The assignemtn operator should look like this:

 class DFoo
 {
     DFoo& operator=(DFoo const& rhs);  // You can only assign DFoo to a DFoo.
                                        // Now there is no way for DFoo1 to get assigned to a DFoo
 };

Also in this trivial example that you posted the default assignent operator generated by the compiler should work as expected. Is there some special reason that you are writting an assignment operator?

Martin York