C ++: Auto_ptr+إعلان إلى الأمام؟
-
21-09-2019 - |
سؤال
لدي فصل مثل هذا:
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 هي ما أوصي به أيضًا.
لم يكن هناك أي خطأ حقًا في استخدام مؤشر عاري لمؤشر التوحيد الخاص بك ، طالما أنك تتصل بحذفه في مدمرك. ربما يجب عليك أيضًا تنفيذ أو تعطيل منشئ النسخ ومشغل المهام.