سؤال

game.h needs:
- packet.h
- socket.h

server.h needs:
- socket.h

socket.h needs:
- game.h

تأتي المشكلة عندما أحاول تضمين Socket.H في Game.H، لأن Socket.h لديه لعبة. ه التي شملت بالفعل. كيف يمكنني حل هذه النوع من المشاكل؟

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

المحلول

الطريقة المعتادة، استخدم #ifdef و # Define في ملفات رأسك

داخل اللعبة

#ifndef GAME_H
#define GAME_H

.. rest of your header file here

#endif

بهذه الطريقة، سيتم قراءة المحتويات عدة مرات، ولكن المعرفة فقط مرة واحدة.

يحرر: إزالتها الشرطة في بداية ونهاية المعرف لكل تعليقات.

نصائح أخرى

المفتاح هو إعلان الأمام. خذ الاشياء من game.h هذا مطلوب في socket.h (أو العكس) وإعلامها في رأس آخر، على سبيل المثال game_forwards.h. وبعد كمثال، فكر في ما يلي:

// game_fwd.h

#ifndef GAME_FWD_H
#define GAME_FWD_H

class game;

#endif // ndef GAME_FWD_H

// game.h

#ifndef GAME_H
#define GAME_H

#include "socket.h"

class game {
    socket* m_sck;
};

#endif // ndef GAME_H

// socket.h

#ifndef SOCKET_H
#define SOCKET_H

#include "game_fwd.h"

class socket {
    game* m_game;
};

#endif // ndef SOCKET_H

من الواضح أن هذا للعمل، من المهم فصل الواجهة والتنفيذ.

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

للكمال، بديل آخر هو:

#pragma once 

في الجزء العلوي من الملف.

هذا لديه ميزة أن الملف لم يتم فتحه بشكل متكرر، وتوفير وقت التحويل.

لديها عيوب عدم كونه معيارا، لذلك لا يدعم ذلك جميع المترجمين. يعمل بشكل موثوق في Visual C ++.

لا يوجد طريقة أنيقة حولها، حيث يمكنني التفكير في - أفضل رهان هو إعادة توجيه الوظائف التي سيتم استخدامها بالفعل. لذلك، إذا كانت اللعبة. H فقط تستخدم وظيفة Connect () من Socket.h، أضف هذا السطر إلى Game.H:

void connect();

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

إذا كانت اللعبة. حاجة فقط لمعرفة فئة في المقبس، إلى الأمام تحديد ذلك مثل هذا:

class Socket;

هناك بعض التحذيرات عندما يتعلق الأمر بالوظائف المضمنة والأشياء الأعضاء، انظر الأسئلة الشائعة C ++ لايت.

@ lassevk، لا ينبغي أن يكون ذلك "سيتم فتح ملف الرأس عدة مرات، ولكن سيتم قراءة Preprocessor فقط محتويات الملف بين #ifndef و #endif مرة واحدة، خلال القراءة الأولى. بعد ذلك، سيتجاهل Preprocessor beTeen تم تعريف وحدات الماكرو PP لأنه _game_h. "

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