لماذا لا يمكن استخدام الإعلان الأمامي ل ستد :: ناقلات؟ [c++]


Answers

في الواقع المثال الخاص بك بناء إذا تم تنفيذ منشئ A في وحدة الترجمة التي تعرف نوع B.

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

إعلان أ:

// A.h
#include <vector>

class B; // Forward declaration.

class A
{
public:
    A(); // only declare, don't implement here

private:
    std::vector<B> v;
};

A:

// A.cpp
#include "A.h"
#include "B.h"

A::A() // this implicitly calls vector<B>'s constructor
{
    std::cout << v.size() << std::endl;
}

الآن مستخدم من يحتاج إلى معرفة فقط A، وليس B:

// main.cpp
#include "A.h"

int main()
{
    A a; // compiles OK
}
Question

إذا قمت بإنشاء فئة مثل ذلك:

// B.h
#ifndef _B_H_
#define _B_H_

class B
{
private:
    int x;
    int y;
};

#endif // _B_H_

واستخدامها مثل هذا:

// main.cpp
#include <iostream>
#include <vector>

class B; // Forward declaration.

class A
{
public:
    A() {
        std::cout << v.size() << std::endl;
    }

private:
    std::vector<B> v;
};

int main()
{
    A a;
}

فشل المترجم عند تجميع main.cpp . الآن الحل الذي أعرفه هو #include "Bh" ، ولكن أنا غريبة لماذا فشل. لم تكن رسائل الخطأ في g++ أو cl 's مستنيرة جدا في هذه المسألة.




انها أكثر من مجرد حجم B التي هناك حاجة إليها. سوف المجمعين الحديثة لديها الحيل الهوى لتسريع نسخ ناقلات باستخدام ممكبي حيثما كان ذلك ممكنا، على سبيل المثال. ويتحقق هذا عادة من خلال التخصص جزئيا على بود-نيس من نوع العنصر. لا يمكنك معرفة ما إذا كان B هو بود من إعلان إلى الأمام.




هذا لا يهم ما إذا كنت تستخدم متجه أو مجرد محاولة إنشاء واحد B. يتطلب إنستانتياتيون التعريف الكامل للكائن.




سبب عدم استخدام إعلان إلى الأمام هو لأن حجم B غير معروف.

ليس هناك سبب في المثال الخاص بك أنه لا يمكنك تضمين ب داخل أه، فما هي المشكلة التي تحاول حقا حلها؟

تحرير: هناك طريقة أخرى لحل هذه المشكلة، أيضا: التوقف عن استخدام C / C ++! انها حتى 1970s ...؛)