Mám dve triedy, Permutáciu a Cyklus. Cyklus je v podstate špeciálnym druhom permutácie, ale nie je to odvodená trieda Permutácie, čiastočne z nasledujúceho dôvodu. Produkt dvoch permutácií je ďalšia permutácia, zatiaľ čo produkt cyklov vo všeobecnosti nie je iným cyklom. cyklus a permutácia je permutácia.
Pre permutácie p1, p2 a cykly c1, c2 dúfam, že zamýšľaný význam nasledujúcich výrokov by mal byť jasný:
Permutation p3 = p1*p2;
Permutation p4 = p1*c1;
Permutation p5 = c1*p1;
Permutation p6 = c1*c2;
Základná štruktúra mojich tried Cyklus a Permutácia je nasledovná:
class Cycle
{
public:
// stuff ...
};
class Permutation
{
public:
Permutation(const Cycle& cycle);
friend
Permutation operator*(const Permutation& left, const Permutation& right);
// stuff ...
};
Ako môžem / mal by som pridať kód (alebo zmeniť kód) tak, aby sa dosiahlo vyššie uvedené použitie?
Mám niekoľko (možno chybných) nápadov:
Prvá myšlienka na zmenu triedy Permutation takto:
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 ...
};
Myslím, že by to fungovalo, ale myslel som si, že by to mohla byť dobrá situácia pre zásobovanie prevádzkovateľa konverzie.
Tu je moja druhá myšlienka:
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 ...
};
Myslím si, že táto druhá myšlienka by mala fungovať pre:
Permutation p4 = p1*c1;
ale nie:
Permutation p5 = c1*p1;
Permutation p6 = c1*c2;
Tretia myšlienka:
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 ...
};
Mám podozrenie, že by to mohlo fungovať
Permutation p4 = p1*c1;
Permutation p5 = c1*p1;
ale nemôžem si predstaviť, že by kompilátor vedel zadať konverziu oboch argumentov v zadaní:
Permutation p6 = c1*c2;
Ďakujeme vopred za vaše pripomienky a návrhy.
bóje
odpovede:
0 pre odpoveď č. 1Myslím, že vaša chyba nie je urobená cyklus odvodený z Permutácie. Toto je môj návrh:
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;
}
}