/ / Кое е по-добре: претоварване оператор * или претоварване оператор гласове? - c ++, преобразуване на типа, претоварване от оператора

Кое е по-добре: претоварване оператор * или претоварване оператор гласове? - c ++, преобразуване на типа, претоварване от оператора

Имам два класа, 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;
}
}