青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Programmer's Cookbook

{C++ 基礎(chǔ)} {C++ 高級(jí)} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

c#運(yùn)算符重載和技巧 (equal()函數(shù)的實(shí)現(xiàn)使用)

Overview

Occasionally this question pops up in newsgroups and forums : Why does C# insist on operator overloads being static? The person raising the question also usually complains how this prevents him or her from implementing virtual overloaded operators.

This article explains why operator overloads have to be static in C# (or any other MSIL compiler), and also shows how you can simulate virtual overloaded operators very easily. It's not a universe-shattering theory (nor a very original one for that matter) and uses a very simple pattern though it's this very simplicity that makes it interesting.

So, why do they have to be static?

In C#, GC'd objects are heap-allocated (the managed CLR heap, not the CRT heap) and thus GC'd objects are always used as references (into the CLR heap). You cannot have stack-based GC'd objects in C# and what this means that you never know when an object variable is null. So, you can imagine what happens if operator overloads were instance methods and you tried to use an operator on a null object! Traditional C++ (as opposed to the CLI version) never faced this problem because the operators were always applied on stack objects; and if at all pointers were used, since pointers followed their own set of operational behavior - you never face a situation where an overloaded op-overload method is invoked on an invalid object.

Traditional C++ example

See below some C++ code that uses virtual operator overloads :-

class Base
{
public:
    Base(int x):x_value(x){}
    virtual bool operator ==(const Base& b)
    {
        return x_value == b.x_value;
    }
protected:
    int x_value;
};

class Derived : public Base
{
public:
    Derived(int x, int y): Base(x), y_value(y){}    
    virtual bool operator ==(const Base& b)
    {        
        Derived* pD = (Derived*)&b;
        return (pD->y_value == y_value) && (pD->x_value == x_value);
    }
private:
    int y_value;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* b1 = new Derived(2,11);
    Base* b2 = new Derived(2,11);

    cout << (*b1==*b2) << endl;

    return 0;
}

When (*b1==*b2) is evaluated the == operator overload for class Derived is invoked which can be easily verified by trying out different values for the Base constructors for b1 and b2 or by setting a breakpoint inside the operator overload.

A port to C#

Taking what we know of C# let's attempt a straight-forward port of the above example to C#.

public class Base
{
    int x;

    public Base( int x )
    {
        this.x = x;
    }

    public static bool operator==( Base l, Base r )
    {
        if( object.ReferenceEquals( l, r ) )
            return true;
        else if( object.ReferenceEquals( l, null ) || 
                 object.ReferenceEquals( r, null ) )
            return false;
            
        return l.x == r.x;
    }

    public static bool operator!=( Base l, Base r )
    {
        return !(l == r);
    }

    public int X { get { return x; } }
}

public class Derived : Base
{
    int y;

    public Derived( int x, int y ) : base( x )
    {
        this.y = y;
    }

    public static bool operator==( Derived l, Derived r )
    {
        if( object.ReferenceEquals( l, r ) )
            return true;
        else if( object.ReferenceEquals( l, null ) || 
                 object.ReferenceEquals( r, null ) )
            return false;
        
        return (l.y == r.y) && (l.X == r.X);
    }

    public static bool operator!=( Derived l, Derived r )
    {
        return !(l == r);
    }

    public int Y { get { return y; } }
}

class Program
{
    static void Main()
    {
        Derived d1 = new Derived( 2, 11 );
        Derived d2 = new Derived( 2, 11 );

        Console.WriteLine( d1 == d2 );
        Console.ReadLine();
    }
}

If we run the program as it is above everything will work like the C++ version, but if we introduce a slight change to the program things begin to deviate greatly.

class Program
{
    static void Main()
    {
        Base d1 = new Derived( 2, 11 );
        Base d2 = new Derived( 2, 12 );

        Console.WriteLine( d1 == d2 );
        Console.ReadLine();
    }
}

What's going on here? As simple debugging will show us the despite the objects being compared being instances of the Derived class the Base class == operator is being called. This is because C# (and thus, most other languages) figure out which == operator method to call based on the known (i.e. compile-time) type of the object on the left hand side of the operation.

There are ways around this as you'll see below.

Simulating operator polymorphism with C#

Here, we see how to simulate this in C# :-

class Base
{
    protected int x_value = 0;    

    public Base(int x)
    {
        x_value = x;
    }

    public static bool operator==(Base b1, Base b2)
    {
        if( object.ReferenceEquals( b1, b2 ) )
        {
            return true;
        }
        else if( object.ReferenceEquals( b1, null ) || 
                 object.ReferenceEquals( b2, null ) )
        {
            return false;
        }
        
        return b1.Equals(b2);            
    }

    public static bool operator !=(Base b1, Base b2)
    {
        return !(b1 == b2);
    }

    public override bool Equals(object obj)
    {
        if( obj == null )
            return false;
        
        Base o = obj as Base;
        
        if( o != null )    
            return x_value == o.x_value;
        return false;
    }


    public override int GetHashCode()
    {
        return x_value.GetHashCode();
    }
}

class Derived : Base
{
    protected int y_value = 0;
    

    public Derived(int x, int y) : base(x)
    {
        y_value = y;
    }

    public override bool Equals(object obj)
    {
        if( !base.Equals( obj ) )
          return false; 
          
        Derived o = obj as Derived;
        
        if( o == null )
            return false;
        
        return y_value == o.y_value;
    }

    public override int GetHashCode()
    {
        return x_value.GetHashCode() ^ y_value.GetHashCode() + x_value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Base b1 = new Derived(10, 12);
        Base b2 = new Derived(10, 11);
        
        Console.WriteLine(b1 == b2);

        b2 = null;

        Console.WriteLine(b1 == b2);

        Console.ReadKey(true);
    }
}

Rather than rely on the == operator overload to do all of the heavy lifting we push all of the work onto the virtual Equals method, from there we let polymorphism work its magic.

Points to note

  • The operator overload has to be static, so we have virtual instance methods that implement the logic for us and we invoke these virtual methods from the static operators

  • In our example, the method Equals corresponds to == and Equals is a virtual method (inherited from System.Object)

  • Within the static overload we need to check for null (to avoid null-reference exceptions)

  • Within each derived class's corresponding operator-logic method (Equals in our case), we cast the System.Object argument to the type of the class (e.g. - In the Derived class we cast to Derived)

  • While Equals and == already exist in System.Object, we can implement similar methods for any operator in our class hierarchies. Say, we need to implement the ++ operator, we then add a PlusPlus (or Increment) virtual method to the root base class in our object hierarchy and in the ++ overload we invoke the Increment method on the passed-in object.

  • In our example, we check for null and return true or false depending on whether the objects are both null or not. But, if you are implementing an operator like ++ then you might want to check for null and throw an ArgumentNullException (to override the inappropriate NullReferenceException that'd otherwise get thrown).

History

  • Apr 19, 2005 : Article first published
  • Apr 20, 2005 : Fixed a bug in Derived.Equals and also changed the GetHashCode implementations for Base and Derived (thanks to Jeffrey Sax for pointing this out)

posted on 2006-03-14 12:35 夢(mèng)在天涯 閱讀(1987) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C#/.NET

公告

EMail:itech001#126.com

導(dǎo)航

統(tǒng)計(jì)

  • 隨筆 - 461
  • 文章 - 4
  • 評(píng)論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1811726
  • 排名 - 5

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              欧美精品精品一区| 久久久久.com| 欧美一级理论性理论a| 免费不卡在线观看av| 国产酒店精品激情| 欧美影院精品一区| 羞羞色国产精品| 国产午夜精品福利 | 国产日韩在线播放| 亚洲在线免费| 久久这里只有| 国产精品亚洲综合一区在线观看| 国产精品久久综合| 亚洲一区二区在线免费观看| 午夜精品福利一区二区三区av| 午夜精品一区二区三区四区| 国产一区亚洲| 国产精品二区三区四区| 午夜精品偷拍| 久久久久久久综合色一本| 亚洲欧洲三级| 亚洲精品看片| 欧美特黄a级高清免费大片a级| 欧美一区二区免费| 久久精品视频免费观看| 亚洲精选一区二区| 美乳少妇欧美精品| 欧美成人蜜桃| 久久成人精品一区二区三区| 欧美激情一区| 免费成人av资源网| 国产精品久久久久久久浪潮网站| 久久中文字幕导航| 欧美va亚洲va香蕉在线| 一区二区三区产品免费精品久久75| 欧美一区视频在线| 亚洲午夜视频在线| 亚洲精品黄色| 激情丁香综合| 欧美成人a视频| 亚洲一区二区在线免费观看视频 | 久久av在线看| 最新日韩在线视频| 欧美成年网站| 久久伊人亚洲| 免费黄网站欧美| 在线精品在线| 亚洲美女网站| 亚洲特级片在线| 亚洲高清三级视频| 亚洲国产日韩欧美在线图片| 国产精品一区在线观看你懂的| 欧美日韩国产不卡在线看| 亚洲一区二区伦理| 亚洲无人区一区| 欧美一区二区视频在线| 午夜日韩av| 久久久久久久久久久久久女国产乱 | 欧美区国产区| 亚洲成色www久久网站| 一区二区三区国产| 亚洲第一二三四五区| 亚洲一区二区三区欧美 | 久久综合久久久| 欧美激情精品久久久久久黑人| 亚洲电影免费观看高清完整版在线观看 | 久久精品国产一区二区电影| 亚洲线精品一区二区三区八戒| 午夜精品久久久久久久久| 国产精品视频xxx| 欧美专区在线| 亚洲性av在线| 亚洲精品美女久久7777777| 亚洲男人的天堂在线观看| 看片网站欧美日韩| 一区精品在线播放| 久久综合中文| 亚洲国产片色| 一本色道久久99精品综合| 欧美日韩国产在线一区| 国产亚洲精品久久久久动| 亚洲天堂av图片| 久久久91精品国产| 亚洲国产精品尤物yw在线观看 | 久久精品五月| 久久精品官网| 久久五月婷婷丁香社区| 免费91麻豆精品国产自产在线观看| 欧美激情久久久久| 亚洲国产电影| 欧美成人一区二区在线| 亚洲国产精品嫩草影院| 亚洲午夜久久久| 国产视频在线一区二区 | 久热精品视频在线| 亚洲精品系列| 国产精品欧美在线| 久久亚洲精选| 在线亚洲欧美视频| 久久久久一区二区三区四区| 伊人久久综合97精品| 欧美日韩高清在线观看| 亚洲欧美日韩在线| 亚洲福利电影| 欧美在线高清| 一区二区三区四区国产| 国产在线国偷精品产拍免费yy| 欧美成人在线免费视频| 亚洲欧美在线视频观看| 亚洲国产美女精品久久久久∴| 午夜在线成人av| 亚洲美女毛片| 一区在线免费观看| 国产精品草草| 欧美激情亚洲一区| 久久久亚洲欧洲日产国码αv| 夜夜嗨av色一区二区不卡| 老司机免费视频久久| 亚洲欧美激情在线视频| 亚洲精品一二| 亚洲国产视频一区| 国产日韩欧美中文在线播放| 欧美日韩免费在线视频| 免费在线播放第一区高清av| 欧美在线免费观看亚洲| 中文欧美字幕免费| 亚洲免费av网站| 欧美风情在线| 欧美成人高清| 久久只精品国产| 久久婷婷国产综合精品青草| 午夜精品久久久久久久蜜桃app | 欧美日韩一区精品| 一本久道久久综合婷婷鲸鱼| 久久国产精品久久国产精品| 国产综合av| 欧美风情在线| 国产毛片一区二区| 久久精品国产99| 裸体素人女欧美日韩| 亚洲精品永久免费精品| 亚洲午夜精品国产| 99亚洲精品| 欧美视频中文字幕在线| 久久精品国产99国产精品澳门 | 99re热这里只有精品免费视频| ●精品国产综合乱码久久久久| 国自产拍偷拍福利精品免费一| 国产伦精品一区二区三区| 国产精品日韩欧美一区| 国产精品久久中文| 国产精品综合网站| 国产麻豆一精品一av一免费| 国产日韩欧美一区| 红桃av永久久久| 亚洲国产精品日韩| 亚洲毛片av在线| 一区二区三区欧美成人| 亚洲欧美日韩国产综合| 欧美在线你懂的| 久久综合福利| 亚洲大胆美女视频| 亚洲精品午夜| 亚洲一区尤物| 久久精品在线免费观看| 欧美成人午夜| 国产精品乱码| 亚洲丶国产丶欧美一区二区三区 | 欧美三级网址| 国内一区二区三区| 亚洲精品久久久久久久久久久久| 99re66热这里只有精品4| 亚洲欧美一区二区视频| 久久久久高清| 亚洲精品视频免费在线观看| 亚洲图中文字幕| 久久一区二区三区超碰国产精品| 欧美激情aaaa| 国产日韩三区| 夜夜嗨av一区二区三区网页| 性久久久久久| 欧美激情影院| 性欧美大战久久久久久久免费观看 | 国产日韩欧美一区| 亚洲激情小视频| 一区二区三区高清在线| 在线观看欧美| 欧美国产日产韩国视频| 久久久久久午夜| 蜜臀久久久99精品久久久久久 | 欧美日韩在线观看视频| 欧美日韩亚洲视频一区| 亚洲欧美国产三级| 免费成人小视频| 一区二区三区国产盗摄| 久久久久国产精品午夜一区| 欧美日韩一区二区三区高清| 永久555www成人免费| 篠田优中文在线播放第一区| 欧美高清免费|