Имам два класа, Permutation и Cycle. Цикълът е по същество специален вид пермутация, но не е произхождащ клас на пермутация, частично поради следната причина: Продуктът на две пермутации е друга пермутация, докато продуктът на циклите обикновено не е друг цикъл. цикъл и пермутация е пермутация.
За пермутациите p1, p2 и цикли c1, c2 се надявам, че трябва да е ясно,
Permutation p3 = p1*p2;
Permutation p4 = p1*c1;
Permutation p5 = c1*p1;
Permutation p6 = c1*c2;
Основната структура на моите класове цикъл и пермутация е, както следва:
class Cycle
{
public:
// stuff ...
};
class Permutation
{
public:
Permutation(const Cycle& cycle);
friend
Permutation operator*(const Permutation& left, const Permutation& right);
// stuff ...
};
Как може / трябва да добавя код (или да променя кода), за да реализирам гореспоменатата употреба по-горе?
Имам няколко (вероятно недостатъчни) идеи:
Първата идея за модифициране на този клас Permutation:
class Permutation
{
friend Permutation operator*(const Permutation&, const Cycle&);
friend Permutation operator*(const Cycle&, const Permutation&);
friend Permutation operator*(const Cycle&, const Cycle&);
public:
Permutation(const Cycle& cycle);
friend
Permutation operator*(const Permutation& left, const Permutation& right);
// stuff ...
};
Мисля, че това ще стане, но мислех, че това може да е добра ситуация за доставяне на оператор за преобразуване.
Ето втората ми идея:
class Permutation
{
public:
Permutation(const Cycle& cycle);
friend
Permutation operator*(const Permutation& left, const Permutation& right);
// stuff ...
};
class Cycle
{
public:
operator Permutation() const
{
Permutation p(*this);
return p;
}
// stuff ...
};
Мисля, че тази втора идея трябва да работи за:
Permutation p4 = p1*c1;
но не:
Permutation p5 = c1*p1;
Permutation p6 = c1*c2;
Ето една трета идея:
class Permutation
{
friend Permutation operator*(const Permutation&, const Permutation&);
public:
Permutation(const Cycle& cycle);
//friend
//Permutation operator*(const Permutation& left, const Permutation& right);
// stuff ...
};
class Cycle
{
public:
operator Permutation() const
{
Permutation p(*this);
return p;
}
// stuff ...
};
Предполагам, че това може да работи
Permutation p4 = p1*c1;
Permutation p5 = c1*p1;
но не мога да си представя, че компилаторът ще знае да въведете конвертиране на двата аргумента в заданието:
Permutation p6 = c1*c2;
Благодарим предварително за вашите коментари и предложения.
Дан
Отговори:
0 за отговор № 1Мисля, че вашата грешка не е цикъл, получен от Permutation. Това е моето предложение:
class Permutation
{
public:
virtual bool IsCycle()
{
return false;
}
virtual Permutation& operator*(Permutation& right);
};
class Cycle: public Permutation
{
public:
virtual bool IsCycle()
{
return true;
}
Permutation& operator*(Permutation& right);
};
Permutation& Permutation::operator*(Permutation& right)
{
// in this case left operand is NOT a Cycle
// right operand could be anything
Permutation& p1 = *this;
if(right.IsCycle())
{
Cycle& c1 = *dynamic_cast<Cycle*>(&right);
// code for case Permutation p4 = p1*c1;
}
else
{
Permutation &p2 = right;
// code for Permutation p3 = p1*p2;
}
}
Permutation& Cycle::operator*(Permutation& right)
{
// in this case left operand IS a Cycle
// right operand could be anything
Cycle& p1 = *this;
if(right.IsCycle())
{
Cycle& c2 = *dynamic_cast<Cycle*>(&right);
// code for case Permutation p6 = c1*c2;
}
else
{
Permutation &p1 = right;
// code for Permutation p5 = c1*p1;
}
}