سؤال

لدي فصل مثل هذا:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    Inner* m_inner;
};

في .CPP ، ينشئ المُنشئ مثيلًا Inner مع new والمدمر deleteيجلس. هذا يعمل بشكل جيد.
الآن أريد تغيير هذا الرمز لاستخدامه auto_ptr لذلك أكتب:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    std::auto_ptr<Inner> m_inner;
};

الآن ، قام المنشئ بتهيئة auto_ptr والمدمر لا يفعل شيئًا.

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

تحذير C4150: حذف المؤشر إلى نوع غير مكتمل "داخلي" ؛ لا يدعى المدمر

حسنًا ، من الواضح أن هذا سيء للغاية وأنا أفهم سبب حدوثه ، لا يعرف المترجم Inner عند إنشاء نموذج auto_ptr<Inner>

لذا سؤالي: هل هناك طريقة للاستخدام auto_ptr مع إعلان إلى الأمام كما فعلت في الإصدار الذي يستخدم فقط مؤشرات عادي؟
الحاجة الى #include كل فصل أعلن أن المؤشر إليه هو متاعب ضخمة وفي بعض الأحيان ، مستحيل فقط. كيف يتم التعامل مع هذه المشكلة عادة؟

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

المحلول

تحتاج إلى تضمين رأس تعريف class Inner في الملف حيث Cont::~Cont() يقع التنفيذ. وبهذه الطريقة لا يزال لديك إعلان إلى الأمام في تحديد رأسه class Cont ويرى المترجم class Inner التعريف ويمكنه استدعاء المدمرة.

//Cont.h
class Inner; // is defined in Inner.h
class Cont 
{ 
    virtual ~Cont(); 
    std::auto_ptr<Inner> m_inner;
};

// Cont.cpp
#include <Cont.h>
#include <Inner.h>

Cont::~Cont()
{
}

نصائح أخرى

تبين أن المشكلة تحدث فقط عندما أقوم بإجراء C'Tor مضمّن. إذا وضعت c'tor في CPP ، بعد تفكك Inner كل شيء على ما يرام.

قد تفكر في Boost :: shared_ptr () بدلاً من ذلك. ليس له أي عيوب عملية بدلاً من الأداء ، وهو أكثر وضوحًا للإعادة إرسال التصريحات:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

على ما يرام ، دون إعلانات إضافية أعلاه.

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

يبدو أنه مثير للسخرية لكنني حلت نفس المشكلة عن طريق الإضافة #include <memory> إلى ملف cont.h.

إن الإعلان الأمامي في الرأس على ما يرام إذا قمت بتطبيق Destructor في ملف Cont.cpp وقمت بتضمين Inner.h ، كما أشار آخرون.

يمكن أن تكون المشكلة في استخدام Cont. في كل CPP الذي يستخدم (ويدمر) ، يتعين عليك تضمين cont.h و inner.h. التي حلت المشكلة في حالتي.

هذا السؤال (حذف الكائن مع المدمرة الخاصة) و هذا السؤال (كيفية كتابة قالب ISCOMPLETE) قد تساعدك.

ليس من المفترض تقنيًا أن تقوم بتثبيت قوالب مكتبة قياسية مع أنواع غير مكتملة ، على الرغم من أنني لا أعرف أي تطبيق حيث لن ينجح هذا. في الممارسة العملية ، إجابة Sharptooth هي ما أوصي به أيضًا.

لم يكن هناك أي خطأ حقًا في استخدام مؤشر عاري لمؤشر التوحيد الخاص بك ، طالما أنك تتصل بحذفه في مدمرك. ربما يجب عليك أيضًا تنفيذ أو تعطيل منشئ النسخ ومشغل المهام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top