/ / Čo je lepšie: preťaženie operátora * alebo operátora preťaženia? - c ++, konverzia typu, preťaženie operátora

Ktorá je lepšia: preťaženie operátora * alebo preťaženie operátora cast? - c ++, typová konverzia, preťaženie operátorom

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ď č. 1

Myslí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;
}
}