سؤال

في C ++ ، يمكنني بسهولة إنشاء مؤشر وظيفة عن طريق أخذ عنوان وظيفة العضو. ومع ذلك ، هل من الممكن تغيير عنوان تلك الوظيفة المحلية؟

أي قل أن لدي funca () و funcb () في نفس الفصل ، تم تعريفه بشكل مختلف. أنا أتطلع إلى تغيير عنوان Funca () إلى عنوان FUNCB () ، بحيث يؤدي الاتصال في وقت التشغيل إلى FUNCA () فعليًا إلى دعوة إلى FUNCB (). أعلم أن هذا قبيح ، لكنني بحاجة إلى القيام بذلك ، شكرًا!

تعديل----------

خلفية حول ما أحاول القيام به:

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

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

العودة إلى الموضوعتتمتع الطريقة Funca () و funcb () بالفعل بنفس التوقيع ، وبالتالي فإن المشكلة هي أنه لا يمكنني الحصول إلا على عنوان وظيفة باستخدام المشغل؟ هل سأكون محقًا في القول إنه لا يمكنني تغيير عنوان الوظيفة ، أو تبديل المحتويات الموجودة في هذا العنوان دون إفساد أجزاء من الذاكرة؟ هل سيكون حقن DLL طريقة جيدة لموقف مثل هذا إذا تم تصدير الوظائف إلى DLL؟

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

المحلول

لا. يتم تجميع الوظائف في المنافسة القابلة للتنفيذ ، ويتم إصلاح عنوانها طوال فترة حياة البرنامج.

أقرب شيء هو وظائف افتراضية. أعطنا مثالاً على ما تحاول إنجازه ، أعدك أن هناك طريقة أفضل.

نصائح أخرى

لا يمكن القيام به بالطريقة التي تصفها. الطريقة الوحيدة لتغيير الهدف لمكالمة ملزمة بشكل ثابت هي تعديل الكود القابل للتنفيذ الفعلي لبرنامجك. لا تحتوي لغة C ++ على ميزات يمكن أن تحقق ذلك.

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

من الناحية الفنية ، قد يكون من الممكن للوظائف الافتراضية من خلال تعديل VTABLE من النوع ، لكنك بالتأكيد لا تستطيع القيام بذلك دون انتهاك المعيار (التسبب في سلوك غير محدد) وسيتطلب معرفة كيفية تعامل برنامج التحويل البرمجي المحدد الخاص بك.

بالنسبة للوظائف الأخرى ، لا يمكن ذلك لأن عناوين الوظائف مكتوبة مباشرة إلى رمز البرنامج ، والذي يكون عمومًا في منطقة ذاكرة للقراءة فقط.

ما تريده هو مؤشر إلى وظيفة ، يمكنك توجيهها إلى Funca أو Funcb على افتراض أن لديهم نفس التوقيع.

أنا متأكد تمامًا من أن هذا مستحيل في C ++ النقي. C ++ ليست لغة ديناميكية.

لا يمكنك فعل ما تريد القيام به مباشرة. ومع ذلك ، يمكنك تحقيق نتيجة مماثلة مع بعض المعايير المختلفة قليلاً ، باستخدام شيء تعرفه بالفعل - مؤشرات الوظائف. يعتبر:

// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();

struct T {
   FunctionPointer Function;
};

الآن يمكنك تعيين ملف Function عضو على أي T على سبيل المثال ، ودعوها. هذا هو أقرب ما يمكنك الحصول عليه بشكل معقول ، وأفترض أنه بما أنك تدرك بالفعل مؤشرات الوظيفة التي تدركها بالفعل هذا الحل.

لماذا لا تقوم بتحرير سؤالك مع وصف أكثر اكتمالا للمشكلة التي تحاول حلها؟ كما هو الحال ، يبدو أنك تحاول أن تفعل شيئًا فظيعًا.

انه سهل!

ل

في وقت التشغيل ، استدعاء FUNCA () ينتج عنه بالفعل دعوة إلى FUNCB ().

اكتب funcA() على غرار ما يلي:

int funcA( int a, int b) {
  return funcB( a, b );
}

:-)

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