/ / जो बेहतर है: ओवरलोडिंग ऑपरेटर * या ओवरलोडिंग कास्ट ऑपरेटर? - सी ++, टाइप-रूपांतरण, ऑपरेटर-ओवरलोडिंग

कौन सा बेहतर है: ओवरलोडिंग ऑपरेटर * या ओवरलोडिंग कास्ट ऑपरेटर? - सी ++, टाइप-रूपांतरण, ऑपरेटर-ओवरलोडिंग

मेरे पास दो वर्ग हैं, क्रमपरिवर्तन और चक्र। एक चक्र अनिवार्य रूप से एक विशेष प्रकार का क्रमपरिवर्तन है, लेकिन यह क्रमिक रूप से निम्नलिखित कारणों से क्रमशः क्रमबद्ध वर्ग नहीं है। दो क्रमपरिवर्तनों का उत्पाद एक और क्रमपरिवर्तन है जबकि चक्र का उत्पाद आमतौर पर एक और चक्र नहीं होता है। चक्र और क्रमपरिवर्तन एक क्रमपरिवर्तन है।

क्रमपरिवर्तन पी 1, पी 2 और चक्र सी 1, सी 2 के लिए, मुझे उम्मीद है कि निम्नलिखित बयानों का इच्छित अर्थ स्पष्ट होना चाहिए:

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 ...
};

ऊपर दिए गए इच्छित उपयोग को समझने के लिए मैं कोड कैसे जोड़ूं (या कोड बदल सकता हूं)?

मेरे पास कुछ (संभावित रूप से त्रुटिपूर्ण) विचार हैं:

इस तरह क्रमपरिवर्तन वर्ग को संशोधित करने का पहला विचार:

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

मुझे लगता है कि आपकी त्रुटि क्रमपरिवर्तन से प्राप्त चक्र नहीं है। यह मेरा सुझाव है:

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