هل من الممكن أن تحدث تقطيع مع مؤشرات ذكية؟
-
20-09-2019 - |
سؤال
إذا فهمت التقطيع بشكل صحيح ، فلا أعتقد أن هذا يمكن أن يحدث مع مؤشرات أو مؤشرات ذكية. على سبيل المثال ، إذا كان لديك:
class A
{
int something;
};
class B : public A
{
int stuff;
int morestuff;
};
int main()
{
std::shared_ptr<B> b(new B());
std::shared_ptr<A> a;
a = b;
}
ما أفهمه هو أن كتلة الذاكرة المخصصة للكائن المشار إليها بواسطة "B" لا تزال كما هي ولا تتغير عند تعيينها إلى المؤشر الذكي "A".
يرجى تأكيد أو رفض فهمي ، أو اسمحوا لي أن أعرف أي عيوب مرتبطة بهذا.
المحلول
لا يزال المؤشر الذكي مؤشرًا ، لذلك لن تسبب هذه المهمة تقطيعًا. يحدث التقطيع فقط عند التعامل مع القيم ، وليس المؤشرات. ومع ذلك ، لاحظ أن القوالب لا تعرف العلاقات بين العناصر الموجودة في النقطة ، لذلك على الرغم من أن B مستمدة من A ، shared_pointer<B>
لا مشتق من shared_pointer<A>
, ، لذا فإن المهمة لا (تلقائيًا) لا تحصل على صوب تلقائي كما لو كان مع المؤشرات الأصلية.
تحرير: التفصيل على النقطة النهائية.
يحدث التقطيع مع القيم ، وليس المؤشرات ، لذلك (بالنظر إلى تعريفاتك لـ A و B) ، شيء مثل:
الفأس = ب ؛
سوف تعمل ، ولكن "شريحة" كائن B ليصبح كائنًا. ومع ذلك ، إذا كان لديك نوع من القالب الذي يحمل مثيل العنصر:
template <class T>
class holder {
T t_;
public:
holder &operator=(T const &t) {
t_ = t;
return *this;
}
holder &operator=(holder const &t) { t_ = t; return *this; }
};
الآن ، إذا حاولنا تعيين قيمة لآخر ، مثل التقطيع:
holder<A> ha;
holder<B> hb;
A a;
B b;
ha = a;
hb = b;
ha = hb;
لن نحصل على تقطيع. بدلاً من ذلك ، سيعطينا المترجم ببساطة خطأً ، ويخبرنا بذلك holder<A>
و holder<B>
ليست الأنواع ذات الصلة ، لذلك لا يمكن أن تحدث المهمة - دون إضافة طاقم صريح ، لن يتم تجميعها ببساطة.
نصائح أخرى
أنت محق ، لكنها ليست هي نفسها: لا يمكنك التقييم a->stuff
.