سؤال

ماذا يفعل مشغل Unary Plus؟ هناك العديد من التعاريف التي وجدتها (هنا و هنا) ولكن لا يزال لدي أي فكرة عما سيتم استخدامه ل. يبدو أنه لا يفعل أي شيء ولكن هناك سبب لذلك، أليس كذلك؟

هل كانت مفيدة؟

المحلول

هناك مزيد من التحميل إذا كنت تشعر بالحاجة؛ لجميع أنواع محددة مسبقا، إنها أساسا غير مرجع.

الاستخدامات العملية لمشغل الحساب غير المرئي غير المرئي محدود للغاية، وتميل إلى الارتباط بعواقب استخدام قيمة في تعبير حسابي، بدلا من المشغل نفسه. على سبيل المثال، يمكن استخدامه لإجبار الاتساع من أنواع غير متكاملة أصغر إلى int, أو تأكد من أن نتيجة تعبير تعامل ك RValue وبالتالي غير متوافق مع غيرconst المعلمة المرجعية. ومع ذلك، سأرسل هذه الاستخدامات بشكل أفضل لرمز الجولف من قابلية القراءة. :-)

نصائح أخرى

في الواقع، UNARY Plus هل افعل شيئا - حتى في C. التحويلات الحسابية المعتادة على المعامل وإرجاع قيمة جديدة، والتي يمكن أن تكون عددا صحيحا من عرض أكبر. إذا كانت القيمة الأصلية عدد صحيح غير ميزي من عرض أقل من int, ، سيتم تغييره إلى signed القيمة كذلك.

عادة ما يكون هذا مهم، لكنه يمكن لها تأثير، لذلك ليس فكرة جيدة استخدام Unary Plus كنوع من "تعليق" يشير إلى أن عدد صحيح إيجابي. النظر في برنامج C ++ التالي:

void foo(unsigned short x)
{
 std::cout << "x is an unsigned short" << std::endl;
}

void foo(int x)
{
 std::cout << "x is an int" << std::endl;
}

int main()
{
 unsigned short x = 5;
 foo(+x);
}

سيعرض هذا "x هو int".

لذلك في هذا المثال، خلق Unary Plus قيمة جديدة مع نوع مختلف و الانحدار.

من K & R Second Edition:

The Unary + جديد مع قياسي ANSI. تمت إضافته للتماثل مع Unary -.

لقد رأيتها المستخدمة في الوضوح، للتأكيد على القيمة الإيجابية كما تختلف عن القيمة السلبية:

shift(+1);
shift(-1);

ولكن هذا هو استخدام ضعيف جدا. الجواب هو بالتأكيد الزائد.

شيء واحد المدمج في unary + هل يتحول lvalue إلى rvalue. على سبيل المثال، يمكنك القيام بذلك

int x;
&x;

لكن لا يمكنك القيام بذلك

&+x;

:)

PS "التحميل الزائد" ليس بالتأكيد الإجابة الصحيحة. غير + كان موروث من ج وليس هناك تحميل مشغل مستوى المستخدم في C.

الشيء الرئيسي Unary + الإنجازات هو الترقية النوع إلى int لأنواع البيانات الأصغر من int-int. قد يكون هذا مفيدا جدا إذا كنت تحاول طباعة بيانات Char باستخدام std::cout كما البيانات الرقمية.

char x = 5;
std::cout << +x << "\n";

يختلف كثيرا عن

char x=5;
std::cout << x << "\n";

انها متاحة أيضا للتحميل الزائد، ولكن في الواقع الزائد الخاص بك ينبغي كن ما يقرب من nop.

إذا كنت بحاجة إلى طباعة القيمة الرقمية للبايت الخام (على سبيل المثال، الأرقام الصغيرة المخزنة ك Char) لتصحيح الأخطاء أو أي سبب، فيمكنك Unary + تبسيط رمز الطباعة. انصح

char c = 42;
cout << c << endl;           // prints "*\n", not what you want in this case
cout << (int)c << endl;      // prints "42\n", ok
cout << +c << endl;          // prints "42\n", much easier to type

هذا هو مجرد مثال سريع. أنا متأكد من أن هناك أوقات أخرى يمكن أن تساعد فيها UNARY + بمعالجة البايتات الخاصة بك أشبه بالأرقام بدلا من النص.

tidbit التاريخية. اعتقدت لجنة توحيد C99 أيضا الاستخدامات الحالية للأجهزة الحاملة غير نادرة إلى حد ما، كما يتضح من النظر في إعادة استخدامها لتحقيق ميزة أخرى في اللغة: تثبيط تقييم زخرفة الترجمة للتعبيرات المستمرة النقطة العائمة. انظر اقتباس التالي من الأساس المنطقي C، القسم F.7.4:

إن إصدار مبكر من هذه المواصفات مسموح بمتخرم حساب ثابت ثابت، ولكنه تمكن من unary + المشغل، عند تطبيقه على المعامل، لمنع تقييم زخرفة الترجمة للتعبيرات المستمرة.

في النهاية، تم عكس الدلالات، مع تقييما وقت التشغيل القسري في معظم السياقات (على الأقل حتى "كما لو كانت" قاعدة)، والقدرة على فرض تقييم زخرفة الترجمة من خلال استخدام المهيئات الثابتة. لاحظ أن الفرق الرئيسي يكمن في حدوث استثناءات النقطة العائمة، وغيرها من إعدادات التقريب أو الدقة العائمة، حيث الحاضر.

ليس كثيرا. الحجة العامة للسماح لحمل الزائد operator+() هو أن هناك بالتأكيد استخدام العالم الحقيقي لتحميل operator-(), ، وسيكون جدا غريب (أو غير متناظرة) إذا كنت تريد السماح بالحمل الزائد operator-() لكن لا operator+().

أعتقد أنني قرأت هذه الحجة لأول مرة من الستروستروب، لكن ليس لدي كتبي معي الحق في التحقق من ذلك. قد اكون مخطئا.

كان Unary Plus موجود في ج، حيث لم يكن شيئا على الإطلاق (مثل auto الكلمة الرئيسية). من أجل عدم وجوده، كان على Stroustrup تقديم عدم التوافق غير المبرر مع C.

بمجرد أن كان في C ++، كان من الطبيعي السماح بوظيفة الزائدة، تماما مثل Unary ناقص، وقد قدمته Stroustrup لهذا السبب إذا لم يكن هناك بالفعل هناك بالفعل.

لذلك، لا يعني شيئا. يمكن استخدامه كنوع من الديكور لجعل الأمور تبدو أكثر إكرااليا، باستخدام +1.5 كما عكس ذلك -1.5 على سبيل المثال. في C ++، يمكن تحميله، ولكن سيكون مربكا إذا operator+() يفعل أي شيء. تذكر القاعدة القياسية: عند التحميل الزائد للمشغلين الحسابين، قم بأشياء مثل intS القيام به.

إذا كنت تبحث عن سبب لماذا هناك، فابحث عن شيء ما حول التاريخ المبكر ل C. أظن أنه لم يكن هناك سبب وجيه، لأن C لم يتم تصميمه بالفعل. النظر في عديمة الفائدة auto الكلمة الرئيسية (من المفترض أن تكون في المقابل static, ، يجري إعادة تدويرها في C ++ 0x)، و entry الكلمة الرئيسية، والتي لم تفعل أي شيء لم يتم حذفها في وقت لاحق في C90). هناك بريد إلكتروني مشهور الذي يقول فيه Ritchie أو Kernighan أنه عندما أدركوا أن إحساس المشغل لديهم مشاكل، كانت هناك بالفعل ثلاثة منشآت مع الآلاف من خطوط التعليمات البرمجية التي لا يريدون كسرها.

لا أستطيع أن أشير إلى أي مصدر لهذا، لكنني جئت إلى فهمه هو لترويج النوع الصريح، مما يعني تحويل نوع الضياع. التي تضعها في الجزء العلوي من التسلسل الهرمي للتحويل،

  • ترقية وظيفية: new_type operator+(old_type)
  • تحويل: new_type(old_type)
  • يقذف: operator(new_type)(old_type)
  • الإكراه: new_type operator=(old_type)

بالطبع، هذا من التفسير الخاص بي للمذكرة في أحد أدلة C / C ++ C / C ++ التي قرأتها حوالي 15 عاما، اعتبرها بحبة ملح.

#include <stdio.h>
int main()
{
    unsigned short x = 5;
    printf ("%d\n",sizeof(+x)); 
    printf ("%d\n",sizeof(x)); 
    return 0;
}

كما هو موضح في المثال أعلاه، فإن Unary + يغير حقا النوع والحجم 4 و 2 على التوالي. غريب أن التعبير + x محسوب بالفعل في المقايف، اعتقدت أنه لم يكن من المفترض أن. ربما يكون ذلك بسبب حقيقة أن Sizeof لديه نفس الأولوية مثل Unary +.

أفترض أنك يمكن أن تستخدمه لتحقيق عدد إيجابي دائما. مجرد التحميل الزائد unary + المشغل ليكون ABS. لا يستحق حقا مربكة زملائك المطورين، إلا إذا كنت ترغب فقط في توضيح التعليمات البرمجية الخاصة بك. ثم تعمل بشكل جيد.

تعديل أعد كتابة تماما، لأنني كنت واياي في إجابتي الأصلية.

يجب أن يسمح لك ذلك بالتعامل مع الإعلان الصريح لنوعك كقيمة إيجابية (أعتقد في معظمها العمليات غير الرياضية). يبدو أن النفي سيكون أكثر فائدة، لكنني أعتقد هنا مثالا على حيث قد تحدث فرقا:

public struct Acceleration
{
    private readonly decimal rate;
    private readonly Vector vector;

    public Acceleration(decimal rate, Vector vector)
    {
        this.vector = vector;
        this.rate = rate;
    }

    public static Acceleration operator +(Acceleration other)
    {
        if (other.Vector.Z >= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public static Acceleration operator -(Acceleration other)
    {
        if (other.Vector.Z <= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public decimal Rate
    {
        get { return rate; }
    }

    public Vector Vector
    {
        get { return vector; }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top