سؤال

لقد قمت بإنشاء فئة تسمى vir، مع نقل الوظيفة:

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     void move(){}
};

(إنه مشتق من فئة ذات متغيرات int x و int y و char sym) لقد استخلصت فئة من هذا ، تسمى subvir:

class subvir:public vir
{
public:
     subvir(int a,int b,char s){x=a;y=b;sym=s;}
     void move();
};
subvir::move()
{
     x++;
     return;
}

وبعد ذلك قمت بإنشاء مصفوفة من vir، ووضعت subvir فيها

subvir sv1(0,0,'Q');
vir vir_RA[1]={sv1};

ولكن عندما أحاول استخدام sv1.move():

vir_RA[0].move();

يستخدم حركة vir ({}) بدلاً من حركة subvir ({x++}).لقد حاولت جعل sv1 vir وvir_RA vir، وقد نجح الأمر، كما أنه يعمل أيضًا عندما أجعلهما كلاهما subvir، ولكني أريد أن يكونا مختلفين.لقد حاولت جعل vir::move() افتراضيًا خالصًا، ولكن بعد ذلك ظهرت لي رسالة خطأ تثبت المصفوفة.هل يعرف أحد كيف يمكنني تشغيل move() عندما أستخدمها من المصفوفة؟

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

المحلول

وتحتاج إلى مجموعة من المؤشرات في هذه الحالة، بدلا من مجموعة واسعة من الحالات. استخدام فير * [] بدلا من فير []

نصائح أخرى

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

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

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     virtual void move(){}
};

وهذا يجعل الطبقة المشتقة move الظاهرية كذلك.ومع ذلك الخاص بك move التعريف يفتقر إلى قيمة الإرجاع ولن يتم تجميعه.يحاول:

void subvir::move()
{
     x++;
     return;
}

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

vir* v[ 2 ] = { new subvir(0, 0, 'Q'), new subvir(10, -10, 'P') };

يجب عليك أيضًا قراءة الأقسام التالية من FAQ Lite C ++:

وشيئين. مجموعة هي مجموعة من وفير وذلك بطبيعة الحال فإنه يستخدم فير :: الخطوة. نقل () ليس أسلوب ظاهري.

ولكن الأهم من ذلك هو تشريح. لا يمكنك وضع فرعية في صفيف. إذا sizeof فير! = sizeof subvir، ومجموعة لن يصطف بشكل صحيح. حاليا هم نفس الحجم. ولكن ماذا يحدث إذا لم تكن.

نعم، أساسا مترجم لا يسمح فرعية في المصفوفات ل يتم تهيئة صفائف بإحكام لحجم نوع، وأنواع فرعية تميل لتكون أكبر من الآباء والأمهات وذلك من شأنه أن يؤدي إلى مشاكل إذا كنت تستطيع تهيئة صفائف مع القيم النوع الفرعي. ماذا يحدث حقا هو المترجم لأول مرة تخصص مجموعة N * الحجم (base_type) بايت. وبعد ذلك نسخ حجم (base_type) بايت لكل من التهيئة شاء. لو كانوا من أنواع مختلفة، فإنها تحصل على اقتطاع، وأشياء غريبة يمكن أن يحدث في التعليمات البرمجية.

واسمحوا لي أن توطيد الأجوبة السابقة.

وهناك في الواقع مسألتين هنا. واحد هو التقطيع. كنت تهيئة مجموعة من virs مع نسخة من subvir. في مثل هذه الحالات شرائح مترجم الجزء فير من subvir ونسخه في مجموعة، لذلك كنت حقا لا تحصل إلا فير الأشياء هناك. الآن في حالة معينة، subvir لا يوجد أعضاء بيانات إضافية غير تلك التي فير، لذلك التقطيع هو منحط إلى حد ما والكائن فير يتطلع الكثير مثل subvir واحد. ومع ذلك، فير وsubvir فئات مختلفة والكائن في مجموعة ينتهي به الأمر كائن فير وليس كائن subvir متنكرا في زي فير. طريقة واحدة أن الفرق بينهما يعبر عمليا، حتى لو كان كل أعضاء البيانات نفسه، هو إذا كان فير وظائف افتراضية مثقلا subvir. في هذه الحالة مؤشر vtable في الكائن في مجموعة من شأنه أن يشير إلى vtable فير، وليس في subvir. بطبيعة الحال، فإنه سيكون أكثر وضوحا إذا كانت subvir لاحتواء أعضاء بيانات إضافية غير موجودة في فير.

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

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

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