لماذا تظهر Code :: Blocks تعريفا متعدد للخطأ؟

أنا أستخدم الرمز هنا وأريد أن تكون جميع الوظائف التي تستدعي وظائف SDL في ملف رأس مختلف بدلاً من ملف .cpp الرئيسي. لذلك قمت بإنشاء ملف جديد يسمى Methods.h. إليك ما تبدو عليه الملفات:

main.cpp:

#include "Methods.h"
...

Methods.h:

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
....

وأزلت جميع الوظائف من الرئيسي ووضعها في Methods.h

عندما أحاول إنشاء المشروع ، فإنه يقول "خطأ تعريف متعدد".

/media/Data1/Projects/OpenGL/Game2/Methods.h|29|multiple definition of `event'|
obj/Debug/main.o:/media/Data1/Projects/OpenGL/Game2/Methods.h|29|first defined here|
obj/Debug/src/Machine.o||In function `drawFrame()':|
/media/Data1/Projects/OpenGL/Game2/Methods.h|29|multiple definition of `drawFrame()'|
obj/Debug/main.o:/media/Data1/Projects/OpenGL/Game2/Methods.h|29|first defined here|
obj/Debug/src/Machine.o||In function `init_GL()':|
/media/Data1/Projects/OpenGL/Game2/Methods.h|73|multiple definition of `init_GL()'|
obj/Debug/main.o:/media/Data1/Projects/OpenGL/Game2/Methods.h|73|first defined here|
obj/Debug/src/Machine.o||In function `init()':|
/media/Data1/Projects/OpenGL/Game2/Methods.h|97|multiple definition of `init()'|
obj/Debug/main.o:/media/Data1/Projects/OpenGL/Game2/Methods.h|97|first defined here|
obj/Debug/src/Machine.o||In function `clean_up()':|
/media/Data1/Projects/OpenGL/Game2/Methods.h|123|multiple definition of `clean_up()'|
obj/Debug/main.o:/media/Data1/Projects/OpenGL/Game2/Methods.h|123|first defined here|
1
أين يشمل الحرس؟ #ifndef METHODS_H_ #define METHODS_H_ ... #endif
وأضاف المؤلف maverik, مصدر
لا يحل المشكلة ولكنه ينصح بشدة باستخدامها لتشمل الحراس في ملفات التضمين.
وأضاف المؤلف maverik, مصدر
شكر. أنا أضعهم. لم تحلها رغم ذلك هل هناك حاجة في حالتي في الواقع؟
وأضاف المؤلف batman, مصدر

2 إجابة

يبدو أن لديك بعض تعريفات الدوال في ملف الرأس ، وهذا يعني أنك ستحصل على تعريف منفصل لكل وظيفة من كل ملف مصدر يتضمن الرأس. يجب أن يتم إعلانها مضمنة حتى يتسنى تحديدها في كل وحدة ترجمة تتضمن العنوان:

// Methods.h
#ifndef METHODS_H
#define METHODS_H

inline void initGL() {
   //do stuff
}

#endif

بدلاً من ذلك ، يمكنك فقط الإعلان عنها في رأس الصفحة ونقل التعريفات إلى ملف مصدر:

// Methods.h
#ifndef METHODS_H
#define METHODS_H

void initGL();

#endif

// Methods.cpp
#include "Methods.h"

void initGL() {
   //do stuff
}

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

inline SDL_Event & event() {
    static SDL_Event instance;
    return instance;
}

هذا لديه ميزة ، وعيب ، أنه بدأ لأول مرة في المرة التي يتم استدعاء الدالة.

3
وأضاف
أشكركم هناك حدث SDL_Event ؛ في Methods.h. أعتزم أن يكون متغير عالمي. الآن لا يمكنني وضع "مضمنة" على هذا ، هل يمكنني ذلك؟
وأضاف المؤلف batman, مصدر
حسنا ، ولكن لماذا يعطي خطأ تعريف متعددة؟ أين هو التعريف المتعدد؟
وأضاف المؤلف batman, مصدر
ولكن لم أقم بتضمين رأسي في ملفات مصدر متعددة. انها فقط في main.cpp
وأضاف المؤلف batman, مصدر
لقد أعلن العديد من ints const في My Methods.h. الغريب أنه لم يتم إثارة أي قضايا حولها.
وأضاف المؤلف batman, مصدر
@ Clearner: لا ، لا يمكنك تضمين ذلك. لقد قمت بتحديث إجابتي مع الخيارات.
وأضاف المؤلف Mike Seymour, مصدر
إذا كان الرأس يحتوي على تعريفات ، وقمت بتضمينه من ملفات مصدر متعددة ، فستحصل على تعريفات متعددة - واحدة من كل ملف مصدر يتضمنها. مضمنة يريح القواعد ، مما يسمح بتعريفات متعددة للدالة طالما كانت جميعها متطابقة.
وأضاف المؤلف Mike Seymour, مصدر
وفقًا لرسائل الخطأ ، يمكنك أيضًا تضمينها من Machine.cpp (أو من عنوان آخر مضمّن من هناك).
وأضاف المؤلف Mike Seymour, مصدر
@ Clearner: إذا كانت const ، فسيكون لديهم رابط داخلي (كما لو تم تعريفهم أيضًا static ) ، لذلك يتم السماح لك بالتعريفات المتعددة.
وأضاف المؤلف Mike Seymour, مصدر

عندما تضيف ملفًا في codeblocks باستخدام ملف file-new-file-source etc ، توجد شاشة تسألك عما إذا كنت تريد تضمين الملف في إصدارات debug والإصدارات. إذا وضعت علامة على المربعات التي تفكر في أنني بالطبع أريد تضمينها ، فلماذا سأضيف الملف؟ ثم codeblocks تلقائيا يتضمن ملفك. عندما تقوم بتضمين الملف في التعليمة البرمجية ، فإنك تقوم بتكرار ما تقوم به تلقائيًا. لذلك ، عند إضافة ملف لا تضع علامة على تلك المربعات لأن النتيجة مربكة للغاية. كان هذا اليوم.

في صحتك

بركة الوحل

1
وأضاف