איך ניתן לדעת האם הפונקציה תיהיה Inline וא לא? [C++] - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

איך ניתן לדעת האם הפונקציה תיהיה Inline וא לא? [C++]


MasterDK

Recommended Posts

יש לי הגדרה של מחלקה בקובץ H

הבנאי והמפרק שלה הם קטנים (2שורות) אם אני מגדיר אותם בתוך H אז הם אוטמטית inline, אבל מה קורה אם אני מגיד אותן ב CPP (שבתוכו אני מגדיר את שאר המתודות של המחלקה)?

אם הם לא inline איך ניתן לגרום להם להיות inline?

	//Constructor
Object::Object()
{
m_NumObj++;
m_Id = m_NumObj;
}

ניסיון להוסיף את המילה inline לפני שם הבנאי הן ב H והן ב CPP גרם לשגיאה:

1>main.obj : error LNK2001: unresolved external symbol "public: __thiscall valo::Object::Object(void)" (??0Object@valo@@QAE@XZ)

אם זה חשוב אני משתמש ב MSVS 2005

תודה מראש.

קישור לתוכן
שתף באתרים אחרים

אמנם אני טיפה חלוד בזה, אבל למיטב זכרוני:

א. אין מה להגדיר פונקציית inline בקובץ cpp, כי אז היא תהיה inline רק לאותו קובץ obj (היא לא מיוצאת כ-inline).

ב. קונסטרקטורים הם לעולם לא inline גם ככה (הקומפיילר פשוט יתעלם מזה).

קישור לתוכן
שתף באתרים אחרים

אמנם אני טיפה חלוד בזה, אבל למיטב זכרוני:

א. אין מה להגדיר פונקציית inline בקובץ cpp, כי אז היא תהיה inline רק לאותו קובץ obj (היא לא מיוצאת כ-inline).

ב. קונסטרקטורים הם לעולם לא inline גם ככה (הקומפיילר פשוט יתעלם מזה).

אתה באמת טיפה חלוד.

ראשית, אין שום בעיה להגדיר inline constructor ואכן עושים את זה הרבה.

שנית, אפשר לחשוב על טעם להגדיר מתודה כ-inline בתוך CPP וגם להכריז עליה מחוץ ל-CPP (בתוך ה-H).

בצורה זו כאשר משתמשים בה מתוך ה-CPP (במימוש של מתודה אחרת, לדוגמא) אתה חוסך קריאה לפונקציה. אולם כיון שהכרזת עליה ב-H, היא נגישה גם מחוץ לקובץ. מצד שני אני כבר לא זוכר מה הסטנדרט מגדיר לגבי זה. בתור התחלה, תנסה ותראה אם זה עובד:


// cl.h
class Foo
{
public:
Foo();

void f();
};

// cl.cpp
Foo::Foo()
{
f();
}

inline void Foo:f()
{
printf("hello!\n");
}

אח"כ נשב ונחטט בסטנדרט.

קישור לתוכן
שתף באתרים אחרים

כן זה עובד. יש לי 3 פונקציות במחלקה שלושתם קצרות (2שורות), בנאי, מפרק ועוד פונקציה, את הפונקציה ההיא ממיששתי ב CPP והגדתי כ inline וזה עובד אבל אני רוצה להגיד דווקא את ה (con/de)structor

כ inline. שניהם עושים רק 2 פעולות אבל אני לא מצליח להגיד אותם כ inline

אני מקבל שגיאות

האם יש דרך נוספת להגדיר אותם inline בלי לשים את המימוש שלהם ב header?

תודה שוב.

קישור לתוכן
שתף באתרים אחרים

כן זה עובד. יש לי 3 פונקציות במחלקה שלושתם קצרות (2שורות), בנאי, מפרק ועוד פונקציה, את הפונקציה ההיא ממיששתי ב CPP והגדתי כ inline וזה עובד אבל אני רוצה להגיד דווקא את ה (con/de)structor

כ inline. שניהם עושים רק 2 פעולות אבל אני לא מצליח להגיד אותם כ inline

אני מקבל שגיאות

האם יש דרך נוספת להגדיר אותם inline בלי לשים את המימוש שלהם ב header?

תודה שוב.

יש באמת שתי דרכים להגדיר פונקציה בתור inline, האחת זה ע"י כתיבת הממימוש בתוך ההכרזה, והשניה באמצעות שימוש במילת המפתח inline

בכלל ככלל מנחה לא נהוג להשתמש ב inline בתוך ההכרזה עצמה, כי למעשה מה שכתוב בחלק ההכרזה הוא החלקים הנראים לעין של המחלקה. המטודות, מי הן ה friendשלהן, וכל דבר שמיוחצן ע"י המחלקה

אין סיבה שלא תוכל להשתמש ב inline מחוץ להכרזה, ולא אמורה להתעורר בעיה. נסה לרשום כאן קוד דוגמה שניסית ולא עבד לך

קישור לתוכן
שתף באתרים אחרים

header

	class Object
{
public:
/** Constructor. Initialize object. */
Object();
/** Destructor. Deinitialize object. */
virtual ~Object();

/**
* Render. Pure virtual function to reder object.
*/
//virtual void Render() = 0;

/**
* GetID. @return Objects uniqe ID number.
*/
const ValoId GetId() const;

private:
...
}

source:

inline Object::Object()
{
m_NumObj++;
m_Id = m_NumObj;
}

//Destructor
inline Object::~Object()
{
if(m_Id == m_NumObj)
m_NumObj--;
}

//GetId
inline const ValoId Object::GetId() const
{
return m_Id;
}

main:

#include <iostream>

#include "object.h"

int main(int argc, char* argv[])
{
valo::Object o1;
return 0;
}

שגיאות:

1>main.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall valo::Object::~Object(void)" (??1Object@valo@@UAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall valo::Object::Object(void)" (??0Object@valo@@QAE@XZ) referenced in function _main
1>C:\Documents and Settings\Home\My Documents\Visual Studio 2005\Projects\valo\Debug\valo.exe : fatal error LNK1120: 2 unresolved externals

private אין שום דבר חוץ מ 2 משתנים.

valo זה שם של namespace

לא ידוע מה הבעיה פה :s07:

קישור לתוכן
שתף באתרים אחרים

מוזר.

אתה בטוח שזכרת לכלול את הקובץ CPP בקומפילציה ובלינק?

כשאתה מוריד את ה-inline זה עובד? יתכן שטעיתי וזה לא בסטנדרט (אבל לא נראה לי).

אני מציע שתשים פה ממש את הקבצים שלך באופן מלא, כדי נוכל לנסות לקמפל.

קישור לתוכן
שתף באתרים אחרים

גם אני חושב שזה מוזר...

בכל מקרה בדקתי כל הקבצים נמצאים בפרוייקט, הגדרות פרוייקט נראות לי בסדר, יכול להיות ש MSVS משחק אותה חכם לא יודע.

בכל מקרה הנא הקבצים:

main.cpp

#include <iostream>

#include "object.h"

int main(int argc, char* argv[])
{
valo::Object o1;
return 0;
}

object.h:

#ifndef _V_OBJECT_H_
#define _V_OBJECT_H_

typedef unsigned short int ValoId; /**< Objects ID. Maximum objects 65535. */

namespace valo{

/**
* Object Class.
* Pure virtual class to describe object.
* All other objects must be inherited from this class.
*/
class Object
{
public:
/** Constructor. Initialize object. */
Object();
/** Destructor. Deinitialize object. */
virtual ~Object();

/**
* Render. Pure virtual function to reder object.
*/
//virtual void Render() = 0;

/**
* GetID. @return Objects uniqe ID number.
*/
const ValoId GetId() const;

private:
ValoId m_Id; /**< Objects uniqe ID number. */
static ValoId m_NumObj; /**< Number of objects. */
};

};

#endif

object.cpp:

#include "object.h"

namespace valo{

ValoId Object::m_NumObj = 0;

//Constructor
inline Object::Object()
{
m_NumObj++;
m_Id = m_NumObj;
}

//Destructor
inline Object::~Object()
{
if(m_Id == m_NumObj)
m_NumObj--;
}

//GetId
inline const ValoId Object::GetId() const
{
return m_Id;
}
};

spiritus asper

ניסיתי השארתי קונסטרקטור ריק והוא מסרב להיתקמפל עם inline, ומתקמפל סבבה בלי.

טוב לא ידוע מה הבעיה, ניסיתי ליצור פרוייקט ב code::blocks ולקמפל אותו אם GCC (דרך MingW) לא יצא... מסתבר שזה לא בעיה של MSVS.

לא יודע מה לעשות.. לא מבין למה זה מוציא לי שגיאה. בכל מקרה אם מישהוא יודע ויכול לעזור אז אנא מכם, אני אבוד לגמרי.

קישור לתוכן
שתף באתרים אחרים

מה שאתה רושם לגביו שהוא inline לא בטוח שיהייה inline. לקומפיילר יש קריזות משלו בעניין הזה. הקומפיילר ינסה גם להפוך כל מתודה שנמצאת בheader לinline.

ואני חושב שלא ניתן ליצור מתודה שמימושה נמצא בCPP כך שהיא תהייה inline.

קישור לתוכן
שתף באתרים אחרים

אתה מתכוון שלא ניתן שב-H יכריזו על פונקציה וב-CPP יממשו אותה עם Inline?

לפי מה שאני רואה בסטנדרט לגבי פוקנציות רגילות (7.1.1) וכן ב-7.1.2 זה אמור לעבוד.

הקטע המוזר זה שאני זוכר שזה אפשרי ושעשיתי את זה בעבר - הקומפיילר יצר גרסה רגילה של הפונקציה עבור שימוש חיצוני רגיל, וכאשר השתמשתי בה בתוךהמימוש של הclass (באותו CPP) אז הוא עשה inline בעצמו.

קישור לתוכן
שתף באתרים אחרים

מעניין. אם שני קומפיילרים מודרנים מוציאים שגיאה, כנראה שזה בלתי אפשרי בשיטה זו.

יש שיטה אחרת שהיא פשוט להגדיר שתי מתודות, אחת לא INLINE שקוראת לזאת שהיא כן INLINE. זה שימושי ב-named constructor idiom.

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...