Explicit Copy member function.

This topic is 4126 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Which is the preferred way? My classes sometimes contain pointers to other classes.
class foo
{
bar* MyBar;
bar2* MyOtherBar;
public:
//This
void copy(const foo& _foo)
{
MyBar = new bar(_foo.MyBar);
MyOtherBar = new bar2(_foo.MyBar);
}

// OR
foo copy()
{
foo tempFoo;
tempFoo->MyBar = new bar(MyBar);
tempFoo->MyOtherBar = new bar2(MyBar);
return tempFoo;
}
};



Share on other sites
Preferred way is a copy constructor and operator=() overload, which you can use to make natural assignments.

class foo{    bar* MyBar;    bar2* MyOtherBar;public:    foo(const foo& _foo)    :           MyBar(new bar(_foo.MyBar)),           MyOtherBar(new bar2(_foo.MyBar) )    {        }    foo &operator=( const foo& _foo )    {           /*           release previous bar pointers           */           delete MyBar;           delete MyOtherBar;            MyBar = new bar(_foo.MyBar);           MyOtherBar = new bar2(_foo.MyBar);      }    // implement destructor and other constructors};

So we can now just use assignments or intialisation:

foo one;
foo two = one; // foo( const foo& )
foo three;
three = two; // foo &foo::operator=( const foo& )

Share on other sites
The safest way to implement raw copying is to implement a copy-constructor and a (preferably no-fail) swap function and implement the copy-assignment operator in terms of the former:
class foo{	public:		foo()			:			my_bar(new int(7))		{		}		foo(foo const & f)			:			my_bar(new int(*f.my_bar))		{		}		~foo()		{			delete my_bar;		}		foo & operator=(foo const & f)		{			foo(f).swap(*this);			return *this;		}	private:		void swap(foo & f)		{			std::swap(my_bar, f.my_bar);		}		int * my_bar;};

Of course, it's even better to avoid raw copying entirely whenever possible and use RAII wrappers instead, like std::vector instead of new[]ed arrays, etc.

Σnigma

Share on other sites
I prefer to disable operator= and copy-construction by default on any class with a non-trivial constructor.

Make private unimplemented operator= and copy constructors.

If I must have an operator= and copy constructor, I try to use smart pointers that make the problem mostly go away.

Only write copy constructors and operator= as a last resort. They have more problems than most people realize.

Share on other sites
Oops. I forgot to mention that I will need to copy derived classes to base class pointers, which is why I cant use a copy constructor or = operator.

Share on other sites
Quote:
 Original post by GrainOops. I forgot to mention that I will need to copy derived classes to base class pointers, which is why I cant use a copy constructor or = operator.

Then you want this. (Or, if the base class pointer in question is in turn a member of some other object, this.)

Share on other sites
Sketchy, but I hope you get the drift:

template<typename T>struct ClonerSmartPtr {  T* data;  operator T*() { return data; }  T* operator->() {return data;}  T& operator*() {return *data;}  ClonerSmartPtr<T>& operator=(T* other) {    other->clone(&data);    return *this;  }};

Now, do you copy references or do you clone?

If you copy references, you need reference counting at the very least.

If you clone references, then you don't want to have to do it manually -- you want a clone pattern.

In either case, doing the code manually is a bad idea. Mistakes are far too easy. So use SmartPtrs (reference counting, auto-cloning, or whatever) instead of raw pointers and decide on your policy by which ones you pick.

All of a sudden the trivial operator= and copy constructor works, because the data storage describes the data copying policy at the same time.