ج ++: وظيفة رأس لا يتم ربط بشكل صحيح من مكتبة إلى إكس

StackOverflow https://stackoverflow.com/questions/500182

  •  20-08-2019
  •  | 
  •  

سؤال

ولدي ملف رأس في مكتبة (alibrary.lib). المكتبة هي مكتبة ثابتة (.LIB) ويربط بشكل صحيح إلى إكس.

والآن، لدي فئة: Vector3d

.
class Vector3d 
{
    void amethod()
    {
       blah
    }

};

Vector3d cross(const Vector3d &v0, const Vector3d &v1) 
{
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

و}

وأعلن Vector3d والمعرفة في ملف رأس (Vector3d. ح). بعد تعريف فئة، وأنا على وظيفة عبر.

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

 flywindow.obj :error LNK2005: "class Vector3d __cdecl cross(class Vector3d const &,class Vector3d const &)" (?cross@@YA?AVVector3d@@ABV1@0@Z) already defined in fly.obj

وأي أفكار؟

والشكر

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

المحلول

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

inline Vector3d cross(const Vector3d &v0, const Vector3d &v1) {
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

}

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

وكان يعمل من دون وضع exlicitly مضمنة لوظائف عضو فئة، لأن وظائف الأعضاء التي تم تعريفها داخل تعريف الفئة هي ضمنا المضمنة.

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

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

ولكن تحديده في ملف .cpp هذا ما المترجمة بشكل منفصل. مضمنة، بطبيعة الحال، وينبغي بعد ذلك انخفض.


واسمحوا لي أن أضيف قائمة صغيرة من التعاريف والإعلانات، فقط للمساعدة في الحفاظ على الأشياء واضحة حول ما يعنيه الإعلان وتعريف الوظائف والطبقات. لاحظ أن كل تعريف هو أيضا إعلانا، ولكن ليس العكس:

// class _declaration_ of boo
class boo;

// class _definition_ of foo.
class foo {
    // member function _declaration_ of bar
    void bar();

    // member function _definition_ of baz
    void baz() { }
};

// function _definition_ of fuzz
inline void fuzz() { }

// function _declaration_ of fezz
void fezz();

نصائح أخرى

والتفسير الأكثر احتمالا هو أن كنت قد حصلت على كود (على وجه التحديد تعريف الصليب) في الملف الخاص بك تتضمن وتشمل الخاص بك يتم تضمينها ملف من قبل اثنين من الملفات المصدر، وبالتالي تعريف مزدوج.

ويجب أن يكون الملفات رأس الإعلانات فيها، وليس التعاريف. الإعلانات (syaing أن شيئا ما موجود) هي أشياء مثل لtypedef ووالإعلانات الطبقة، والتعداد وهلم جرا.

وتعاريف (إعطاء معنى لTHOS أشياء موجودة) وأشياء مثل وظائف والتعاريف varialble وهلم جرا.

ويجب أن تعلن وظيفة صليبك في ملف الرأس:

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

ولكن محددة في ملف مصدر مستقل.

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