<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Operatoren und abgeleitete Klassen]]></title><description><![CDATA[<p>Guten Tag,</p>
<p>ich habe folgendes Problem. Für einen Interpreter benötige ich<br />
verschiedene Variablentypen. Das können z.B. double, int oder auch chars sein.<br />
Diese Variablen möchte ich in Klassen Kapseln welche alle vom Ursprungstyp CVariable sind (also abgeleitet).<br />
Im späteren Verlauf möchte ich diese abgeleitete Typen untereinander verlgeichen oder verrechnen. Hierzu implementiere ich die entsprechenden operatoren in den abgeleiteten Klassen. Dies sieht dann wie folgt aus:</p>
<pre><code>#ifndef _TYPES_H_
#define _TYPES_H_

class CVariable
{
public:
	CVariable(){}	
private:
};

// class prototype
class CInteger;
class CDouble : public CVariable
{
	// friends
	friend class CDouble;
	friend class CInteger;

public:
	CDouble(double dValue) : m_dValue(dValue){}
	CDouble(const CInteger&amp; val);
	CDouble(const CDouble&amp; val);
	// operators
	virtual CDouble operator*(const CDouble&amp; Val) const;
	virtual CDouble operator*(const CInteger&amp; Val) const;

private:
	CDouble();
	double m_dValue;
};

class CInteger : public CVariable
{
public:
	friend class CInteger;
	friend class CDouble;
	CInteger(int iValue) : m_iValue(iValue){}
	CInteger(const CDouble&amp; val);
	CInteger(const CInteger&amp; val);

	// operators
	virtual CInteger operator*(const CDouble&amp; Val) const;
	virtual CInteger operator*(const CInteger&amp; Val) const; 

private:
	CInteger();
	int m_iValue;
};
#endif

// Implementierung
#include &quot;Types.h&quot;

CDouble CDouble::operator*(const CDouble&amp; Val) const
{
	return CDouble(m_dValue * Val.m_dValue);
}	
CDouble CDouble::operator*(const CInteger&amp; Val) const
{
	return CDouble(m_dValue * Val.m_iValue);
}	
CDouble::CDouble(const CInteger&amp; val)
{
	m_dValue = val.m_iValue;
}
CDouble::CDouble(const CDouble&amp; val)
{
	m_dValue = val.m_dValue;
}

CInteger CInteger::operator*(const CDouble&amp; Val) const 
{
	return CInteger(m_iValue * Val.m_dValue);
}
CInteger CInteger::operator*(const CInteger&amp; Val) const 
{
	return CInteger(m_iValue * Val.m_iValue);
}

CInteger::CInteger(const CDouble&amp; val)
{
	m_iValue = static_cast&lt;int&gt;(val.m_dValue);
}
CInteger::CInteger(const CInteger&amp; val)
{
	m_iValue = val.m_iValue;
}

// main
int _tmain(int argc, _TCHAR* argv[])
{
	CVariable *pFirst,*pSecond,*pRes;
	pFirst = new CDouble(1.23);
	pSecond = new CDouble(2.22);
	pRes = new CDouble(0);

	/* so funktioniert es */
	*static_cast&lt;CDouble*&gt;(pRes) = *static_cast&lt;CDouble*&gt;(pFirst) *
*static_cast&lt;CDouble*&gt;(pSecond);
	/* so nicht */
	*pRes = *pFirst * *pSecond;
	return 0;
}
</code></pre>
<p>Wie in Main gezeigt funktioniert das ganze auch wenn ich zuvor die Typen auf entsprechend Caste. Das würde ich aber gerne vermeiden. Mir ist auch klar dass die Basisklasse die entsprechenden prototpyen der abgeleitetn Klasse nicht kennt, also dessen Operatoren.<br />
Ich vermute der Ansatz wird schon entsprechend verkehrt sein.<br />
Wenn jemand eine gute Idee hat wäre ich sehr dankbar.</p>
<p>Gruß<br />
Holger</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/263780/operatoren-und-abgeleitete-klassen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 12:03:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/263780.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 26 Mar 2010 13:09:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Operatoren und abgeleitete Klassen on Fri, 26 Mar 2010 13:09:48 GMT]]></title><description><![CDATA[<p>Guten Tag,</p>
<p>ich habe folgendes Problem. Für einen Interpreter benötige ich<br />
verschiedene Variablentypen. Das können z.B. double, int oder auch chars sein.<br />
Diese Variablen möchte ich in Klassen Kapseln welche alle vom Ursprungstyp CVariable sind (also abgeleitet).<br />
Im späteren Verlauf möchte ich diese abgeleitete Typen untereinander verlgeichen oder verrechnen. Hierzu implementiere ich die entsprechenden operatoren in den abgeleiteten Klassen. Dies sieht dann wie folgt aus:</p>
<pre><code>#ifndef _TYPES_H_
#define _TYPES_H_

class CVariable
{
public:
	CVariable(){}	
private:
};

// class prototype
class CInteger;
class CDouble : public CVariable
{
	// friends
	friend class CDouble;
	friend class CInteger;

public:
	CDouble(double dValue) : m_dValue(dValue){}
	CDouble(const CInteger&amp; val);
	CDouble(const CDouble&amp; val);
	// operators
	virtual CDouble operator*(const CDouble&amp; Val) const;
	virtual CDouble operator*(const CInteger&amp; Val) const;

private:
	CDouble();
	double m_dValue;
};

class CInteger : public CVariable
{
public:
	friend class CInteger;
	friend class CDouble;
	CInteger(int iValue) : m_iValue(iValue){}
	CInteger(const CDouble&amp; val);
	CInteger(const CInteger&amp; val);

	// operators
	virtual CInteger operator*(const CDouble&amp; Val) const;
	virtual CInteger operator*(const CInteger&amp; Val) const; 

private:
	CInteger();
	int m_iValue;
};
#endif

// Implementierung
#include &quot;Types.h&quot;

CDouble CDouble::operator*(const CDouble&amp; Val) const
{
	return CDouble(m_dValue * Val.m_dValue);
}	
CDouble CDouble::operator*(const CInteger&amp; Val) const
{
	return CDouble(m_dValue * Val.m_iValue);
}	
CDouble::CDouble(const CInteger&amp; val)
{
	m_dValue = val.m_iValue;
}
CDouble::CDouble(const CDouble&amp; val)
{
	m_dValue = val.m_dValue;
}

CInteger CInteger::operator*(const CDouble&amp; Val) const 
{
	return CInteger(m_iValue * Val.m_dValue);
}
CInteger CInteger::operator*(const CInteger&amp; Val) const 
{
	return CInteger(m_iValue * Val.m_iValue);
}

CInteger::CInteger(const CDouble&amp; val)
{
	m_iValue = static_cast&lt;int&gt;(val.m_dValue);
}
CInteger::CInteger(const CInteger&amp; val)
{
	m_iValue = val.m_iValue;
}

// main
int _tmain(int argc, _TCHAR* argv[])
{
	CVariable *pFirst,*pSecond,*pRes;
	pFirst = new CDouble(1.23);
	pSecond = new CDouble(2.22);
	pRes = new CDouble(0);

	/* so funktioniert es */
	*static_cast&lt;CDouble*&gt;(pRes) = *static_cast&lt;CDouble*&gt;(pFirst) *
*static_cast&lt;CDouble*&gt;(pSecond);
	/* so nicht */
	*pRes = *pFirst * *pSecond;
	return 0;
}
</code></pre>
<p>Wie in Main gezeigt funktioniert das ganze auch wenn ich zuvor die Typen auf entsprechend Caste. Das würde ich aber gerne vermeiden. Mir ist auch klar dass die Basisklasse die entsprechenden prototpyen der abgeleitetn Klasse nicht kennt, also dessen Operatoren.<br />
Ich vermute der Ansatz wird schon entsprechend verkehrt sein.<br />
Wenn jemand eine gute Idee hat wäre ich sehr dankbar.</p>
<p>Gruß<br />
Holger</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874176</guid><dc:creator><![CDATA[HolgerW]]></dc:creator><pubDate>Fri, 26 Mar 2010 13:09:48 GMT</pubDate></item><item><title><![CDATA[Reply to Operatoren und abgeleitete Klassen on Wed, 31 Mar 2010 00:56:04 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Diese Problematik, wie auch das Klassendesign, lässt sich mit Templates Lösen.<br />
Der folgende Code erfordert, einen Compiler mit C++0x Unterstützung. Falls du keinen hast musst du dir die type_traits selbst zusammenbasteln oder auf Boost::type_traits zurückgreifen.</p>
<pre><code class="language-cpp">#include &lt;typeinfo&gt;
#include &lt;type_traits&gt;
#include &lt;iostream&gt;

template&lt;typename T=void&gt;
struct Variable;

template&lt;&gt;
struct Variable&lt;&gt;{};  //missbrauche ich mal als Parent und Identifier

template&lt;typename T&gt;
struct Variable : Variable&lt;&gt;
{
typedef T Type;
Type Data;

Variable()=default;
Variable(T const&amp; D): Data{D} {}

template&lt;typename T2&gt;
Variable(Variable&lt;T2&gt; const&amp; D): Data{(T)D.Data} {}

template&lt;typename T2&gt;
Variable&lt;T&gt;&amp; operator=(Variable&lt;T2&gt; const&amp; RHS)
    {
    	this-&gt;Data = RHS.Data;
    	return *this;
    }

template&lt;typename T2&gt;
Variable&lt;T&gt;&amp; operator+=(Variable&lt;T2&gt; const&amp; RHS) // operator+ global über += implementieren
    {
     this-&gt;Data+=static_cast&lt;T&gt;(RHS.Data);
     return *this;
    }
};

struct Integer2 : public Variable&lt;int&gt;
{
//using Variable&lt;int&gt;::Variable; leider noch nicht unterstützt

Integer2(int const&amp; D): Variable&lt;int&gt;(D) {}

template&lt;typename T2&gt;
Integer2(Variable&lt;T2&gt; const&amp; D): Variable&lt;int&gt;(D) {}

};

//Template-Magie ;-)

template&lt;typename A , typename B&gt;
struct DeclType
{
  A a;
  B b;
  typedef decltype( a + b ) Type;
};

template&lt;class lhs ,class rhs&gt;
typename std::enable_if&lt; std::is_base_of&lt;Variable&lt;&gt;,lhs&gt;::value &amp;&amp;
                         std::is_base_of&lt;Variable&lt;&gt;,rhs&gt;::value,
                         Variable&lt; typename DeclType&lt;typename lhs::Type,typename rhs::Type&gt;::Type &gt;
                        &gt;::type operator+(lhs const&amp; LHS, rhs const&amp; RHS)
                        {
                            return Variable&lt; typename DeclType&lt;typename lhs::Type,typename rhs::Type&gt;::Type &gt;(LHS.Data+RHS.Data);
                        }

int main()
{
Variable&lt;int&gt; I{1};
Variable&lt;float&gt; B(3.14);
Integer2 I2(3);

I=2;

auto X= I + B + I2;

std::cout&lt;&lt; I.Data&lt;&lt;&quot; + &quot; &lt;&lt;B.Data&lt;&lt;&quot; = &quot;&lt;&lt; X.Data;

}
</code></pre>
<p>Wirst du anschliesend noch Strukturen darstellen wollen, empfehle ich Variable auf Variadic Templates aufzurüsten.</p>
<p>MFG Speed</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1875789</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1875789</guid><dc:creator><![CDATA[Speed]]></dc:creator><pubDate>Wed, 31 Mar 2010 00:56:04 GMT</pubDate></item><item><title><![CDATA[Reply to Operatoren und abgeleitete Klassen on Wed, 31 Mar 2010 08:31:31 GMT]]></title><description><![CDATA[<blockquote>
<p>Das können z.B. double, int oder auch chars sein.<br />
Diese Variablen möchte ich in Klassen Kapseln welche alle vom Ursprungstyp CVariable sind (also abgeleitet).</p>
</blockquote>
<p>Typische Interpreter loesen das mittels Union.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1875840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1875840</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 31 Mar 2010 08:31:31 GMT</pubDate></item><item><title><![CDATA[Reply to Operatoren und abgeleitete Klassen on Wed, 31 Mar 2010 08:57:47 GMT]]></title><description><![CDATA[<p>Das Problem was du mit den Vergleichen über die Basisklasse hast, nennt sich double Dispatch - schau mal ob du da bei google was findest <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1875853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1875853</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 31 Mar 2010 08:57:47 GMT</pubDate></item></channel></rss>