Re: Problem with copy constructor.
Hi,
Thanks for your time/help on this.
Top-level const's are meaningless.
const Factor *next, const Factor *same);
I'm not sure what you mean by this. You're saying it is not necessary
to make the arguments to constructors as const?
What's "NodePtr"?
It is typedef boost::shared_ptr<class Node> NodePtr;
The "Rule of Three" is violated here.
Here is what I have now. Is this correct way?
struct FactorImpl
{
FactorTypeT type;
int idx;
struct FactorImpl *nextlevel;
struct FactorImpl *samelevel;
FactorImpl()
: type(FACTOR_UNKNOWN), idx(-1), nextlevel(0), samelevel(0) {}
// copy
FactorImpl(const FactorImpl& rhs)
: type(rhs.type), idx(rhs.idx), nextlevel(0), samelevel(0)
{
if (rhs.nextlevel)
nextlevel = new FactorImpl(*rhs.nextlevel);
if (rhs.samelevel)
samelevel = new FactorImpl(*rhs.samelevel);
}
// destructor
~FactorImpl()
{
delete nextlevel;
delete samelevel;
}
// helper for assignment
void swap(FactorImpl& rhs)
{
std::swap(type, rhs.type);
std::swap(idx, rhs.idx);
std::swap(nextlevel, rhs.nextlevel);
std::swap(samelevel, rhs.samelevel);
}
// assignment
FactorImpl& operator=(const FactorImpl& rhs)
{
FactorImpl tmp(rhs);
tmp.swap(*this);
return *this;
}
};
class Factor
{
private:
struct FactorImpl *fact;
Factor();
Factor(const FactorTypeT type, const int index,
const Factor *next, const Factor *same);
Factor(const Factor& rhs);
Factor& operator=(const Factor& rhs);
void swap(Factor& rhs);
static FactorPtr convNodeToFactor(const NodePtr& n, const NodePtr&
ntree);
static FactorPtr convNodeToFactorRecur(const NodePtr& n, const
NodePtr& ntree);
public:
~Factor();
static FactorPtr create();
static FactorPtr create(const FactorPtr& rhs);
void dump(std::ostream& f);
// I have a private ctor/assignment operator. I don't want the user
to be able to do assignment outside
// the class. Also I have done typedef boost::shared_ptr<Factor>
FactorPtr so the object is returned via a boost_shared ptr since it
will get attached to a node.
};
Factor::Factor()
: fact(new FactorImpl()) {}
Factor::Factor(const FactorTypeT type, const int index,
const Factor *next, const Factor *same)
: fact(new FactorImpl())
{
fact->type = type;
fact->idx = index;
if (next)
fact->nextlevel = new FactorImpl(*next->fact);
if (same)
fact->samelevel = new FactorImpl(*same->fact);
}
Factor::~Factor()
{
delete fact;
}
// copy constructor
Factor::Factor(const Factor& rhs)
: fact(new FactorImpl(*rhs.fact)) {}
// helper for assignment
void Factor::swap(Factor& rhs)
{
std::swap(fact, rhs.fact);
}
// assignment operator
Factor& Factor::operator=(const Factor& rhs)
{
Factor tmp(rhs);
tmp.swap(*this);
return *this;
}
// public static create functions
FactorPtr Factor::create()
{
FactorPtr f(new Factor());
return f;
}
FactorPtr Factor::create(const FactorPtr& rhs)
{
FactorPtr f(new Factor(*rhs));
return f;
}
Also, there is no need to verify that the pointer is non-null before
using 'delete' on it.
Thanks for that.
Also, you have memory leaks -- in the FactorImpl::operator= you don't
deallocate (delete) the pointers.
Yes I see it now.
Also, using the assignment operator in the copy-constructor is counter-
intuitive. Using them the other way around might be OK...
I think i'll use the swap/copy constructor to implement the assignment
operator. The above code seems to work. Thanks for your time and help
again.