سؤال

التحديث 1:

تصحيح رمز هراء! شكرا لتعليقات، لقد صنعت التجزئة من المقتطف الأول، عفوا.

تحديث 2:

أيضا عنوان الأسئلة المحدثة، حيث تم الإشارة إلى استخدام Dynamic_Cast غير ضروري إجابات.

ما أحاول تحقيقه هنا هو نسخة عميقة باستخدام أنواع قوية؛ أريد أن أكون قادرا على نسخ الفصل 2 إلى مثيل آخر من الفصل 2؛ ومع ذلك، أريد أيضا استخدام وظيفة النسخة من الفئة 1 التي هي القاعدة. تأتي هذه الفكرة من تجربتي C #، حيث عادة ما سأجعل فقط نوع الإرجاع عام (انظر C # Snippet).

void Class1::CopyTo(Class1 *c1)
{
    // Write data in to c1 from this instance.
    c1->exampleData = exampleData;
}

// Class2 inherits Class1
Class2 *Class2::Copy()
{
    Class2 *c2a = new Class2();
    CopyTo(c2a);

    Class2 *c2b = dynamic_cast<Class2*>(c2a);
    return c2a;
}

وهنا هي الطريقة التي كنت سأفعلها في C #:

public class Class1
{
    T Copy<T>()
        where T : Class1
    {
        /* Can't remember the best way to do this in C#;
         * basically if T was Class2 this would need to create
         * a new instance of that class, and the same goes for
         * Class1. */         
        T copy = createNewInstance();

        // Copy the data from this to 'copy'.
        copy.exampleData = exampleData;

        return copy;
    }
}

الآن، مقارنة مع Snippet C #، فإن المقتطف C ++ يشعر رائحة كريهة. هل من الممكن القيام بذلك دون مؤشرات، أو هل هذه الطريقة أفضل الممارسات؟

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

المحلول

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

template <typename T>
T Class1::Copy()
{
    T instance;
    CopyTo(&instance);
    return instance;
}

هذا يعمل لأنك تمر مؤشر (متعدد الجنس) إلى instance إلى CopyTo طريقة Class1.

ثم يمكنك استدعاء التعليمات البرمجية مثل هذا:

Class2 x1;
// Fill x1
Class2 x2 = x1.Copy<Class2>();

ومع ذلك، هذا الرمز ما يزال تنبعث منه رائحة لأنه ليس one oriomatic c ++: في C ++، يمكنك عادة كتابة منشئ نسخة بدلا من ذلك. في وقت متأخر Copy توجد الأساليب ولكنها نادرا ما تكون مطلوبة للغاية، وما سبق غير موجود (ولكن لا يوجد كود C #).

نصائح أخرى

لست واضحا ما تسأله، ولكن كن على علم بذلك عندما تقول:

 Class2 *c2 = dynamic_cast<Class2*>(c1);

قد تكون نتيجة المصبورة فارغة ويجب التحقق من ذلك.

يجب أن تعمل على مقتطف التعليمات البرمجية أكثر قليلا.GetSomThethingCopy يقوم بإنشاء مؤشر من نوع Class2 الذي يتم تمريره إلى Copyto. يحاول Copyto استدعاء وظيفة عضو للمؤشر المستلم الذي لم تتم تهيئته أبدا: خطأ تجزئة وفاة البرنامج.

حتى لو لم يقتل هذا التطبيق، فأنت تحاول Dynamic_Cast. من class2 * إلى class2 * وهذا هو مجرد عدم القيام بأي شيء. إذا كان ما تعتزمه هو إلقاء القيمة التي تم إرجاعها من Copyto، يجب أن تعرف أنه لا يمكنك استخدام Dynamic_Cast على الفراغ *. يجب عليك إما تغيير توقيع Copyto لإرجاع Class1 (بحيث يمكنك إلقاءها لاحقا) أو استخدم Static_Cast على الفراغ *.

لاحظ أن إما النسخة هي وظيفة افتراضية في Class1 التي تنفدت في الواقع في Class2 وتنشئ كائن Class2، أو غير ذلك، لن يكون العنصر المرتجع فئة 2 فئة، بل بدلا من الفئة 1.

اسم الطريقة المنقسمة مربكة لأنه لا نسخ ل الحجة ولكن بدلا من الحجة.

وبعد كل هذا، ما زلت لا أعرف ما الذي تسأل عنه. أين تريد استخدام ذاكرة مكدس؟ يمكنك تمرير عنصر مخصص كومة إلى وظيفة، ولكن إرجاع مؤشر / مرجع إلى عنصر مخصص للمكدس هو خطأ تجزئة مرة أخرى: سيتم تدمير الكائن عند انتهاء الوظيفة وسيتم ترك جهاز الاستقبال بمؤشر / مرجع تتدلى.

الآن، إذا كان سؤالك هو أكثر نظرية حول ما إذا كان يمكنك استخدام Dynamic_Cast على عنصر مخصص للمكدس، فيمكنك (شريطة أن يرث الفئة 2 من الفصل 1):

void f()
{
   Class2 c2;
   Class1 &c1 = c2; // c1 is a Class1 reference to a Class2 object

   dynamic_cast<Class2&>(c1).class2method(); 
   // or:
   dynamic_cast<Class2*>(&c1)->class2method();
}

إذا قمت بتحديث التعليمات البرمجية، فقم بنشر تعليق في هذه الإجابة حتى ألاحظ ويمكنه تصحيحه الليلة.

هذا الرمز ليس له معنى كما هو مذكور ... على أي حال "أعتقد" يمكنك استخدام المصبوب الثابت إذا لم تستخدم الفراغ * كارجع؟

موافق الآن الرمز منطقي.

لا تحتاج إلى أي ممثلين ديناميكي، بالفعل من النوع Class2.

في وظيفة النسخمة الخاصة بك، ستعود إلى مؤشر إلى كائن تم إنشاؤه على المكدس - هذا استحالة لأن الكائن سيتم تدمير نقاط المؤشر عند إرجاع الوظيفة.

في الإجابة على سؤالك، يمكنك استخدام dynamic_cast على مؤشر أو مرجع. في حالتك، قد أخصص الكائن المراد إرجاعه بشكل حيوي باستخدام new بدلا من المكدس، ثم يمكنك إرجاع مؤشر بأمان. ومع ذلك، أميل إلى النظر إلى استخدام dynamic_cast كشم رائحة رمز محتملة، علامة على أنه يجب استخدام وظيفة افتراضية.

لا، يعمل Dynamic_Cast فقط مع المؤشرات والمراجع. لا يمكنك إرجاع أي شيء تخصصته على المكدس بأمان على أي حال، لذلك لست متأكدا من أن كنت تنوي تعديل التعليمات البرمجية الخاصة بك في هذه الحالة.

آه، والآن المشكلة واضحة. الجواب لا يوجد من الناحية الفنية، وليس withh dynamic_cast <>، لكنني فعلا حقا أن أرى لماذا تريد ذلك على أي حال. يبدو أنك تريد فقط

void Class1::CopyTo(Class1& c1)
{
    // Write data in to c1 from this instance.
    c1.SomeIntValue = SomeIntValue;
}

// Class2 inherits Class1
Class2* Class2::Copy()
{
    Class2 *c2 = new Class2();
    CopyTo(*c2);
    return c2;
}
//or more idiomatic
Class2 Class2::Copy()
{
    Class2 c2
    CopyTo(c2);
    return c2;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top