ইনলাইন ভার্চুয়াল ফাংশনগুলি কি আসলেই একটি অজ্ঞান?


172

আমি এই প্রশ্নটি পেয়েছি যখন আমি একটি কোড পর্যালোচনা মন্তব্য পেয়েছিলাম যাতে বলে ভার্চুয়াল ফাংশনগুলি ইনলাইন হওয়া উচিত নয়।

আমি ভেবেছিলাম যে ইনলাইন ভার্চুয়াল ফাংশনগুলি এমন পরিস্থিতিতে দেখা যায় যেখানে ফাংশনগুলিকে সরাসরি বস্তুগুলিতে ডাকা হয়। তবে পাল্টা যুক্তিটি আমার মনে এলো - কেন কেউ ভার্চুয়ালকে সংজ্ঞায়িত করতে এবং তারপরে পদ্ধতিগুলি কল করতে অবজেক্টগুলি ব্যবহার করতে চায়?

ইনলাইন ভার্চুয়াল ফাংশনগুলি না ব্যবহার করা কি ভাল, যেহেতু সেগুলি প্রায় কোনওভাবেই প্রসারিত হয় না?

কোড স্নিপেট আমি বিশ্লেষণের জন্য ব্যবহার করেছি:

class Temp
{
public:

    virtual ~Temp()
    {
    }
    virtual void myVirtualFunction() const
    {
        cout<<"Temp::myVirtualFunction"<<endl;
    }

};

class TempDerived : public Temp
{
public:

    void myVirtualFunction() const
    {
        cout<<"TempDerived::myVirtualFunction"<<endl;
    }

};

int main(void) 
{
    TempDerived aDerivedObj;
    //Compiler thinks it's safe to expand the virtual functions
    aDerivedObj.myVirtualFunction();

    //type of object Temp points to is always known;
    //does compiler still expand virtual functions?
    //I doubt compiler would be this much intelligent!
    Temp* pTemp = &aDerivedObj;
    pTemp->myVirtualFunction();

    return 0;
}

1
এসেম্বলারের তালিকা পেতে আপনার যা প্রয়োজন স্যুইচ দিয়ে একটি উদাহরণ সংকলন করার বিষয়ে বিবেচনা করুন এবং তারপরে কোড রিভিউর দেখানো হচ্ছে যে, সংকলকটি ভার্চুয়াল ফাংশনগুলিকে ইনলাইন করতে পারে।
থমাস এল Holaday

1
উপরেরগুলিতে সাধারণত ইনলাইন করা হবে না, কারণ আপনি বেস শ্রেণীর সহায়তায় ভার্চুয়াল ফাংশনটি কল করছেন। যদিও এটি কেবল সংকলকটি কতটা স্মার্ট তার উপর নির্ভর করে। যদি এটি চিহ্নিত করতে সক্ষম হয় যে এটি pTemp->myVirtualFunction()অ-ভার্চুয়াল কল হিসাবে সমাধান করা যেতে পারে তবে এটির কলটি ইনলাইন থাকতে পারে। এই রেফারেন্সড কলটি জি ++ 3.4.2 দ্বারা অন্তর্ভুক্ত রয়েছে: TempDerived & pTemp = aDerivedObj; pTemp.myVirtualFunction();আপনার কোডটি নয়।
ডক

1
জিসিসি আসলে একটি জিনিস যা একটি নির্দিষ্ট চিহ্নের সাথে ভেটেবল এন্ট্রি তুলনা করে এবং তারপরে মেলে যদি একটি লুপে একটি অন্তর্নিহিত রূপটি ব্যবহার করে। এটি বিশেষত কার্যকর যদি ইনলাইনড ফাংশনটি ফাঁকা থাকে এবং লুপটি এই ক্ষেত্রে মুছে ফেলা যায়।
সাইমন রিখটার

1
@ ডক আধুনিক সংকলক পয়েন্টারের সম্ভাব্য মানগুলি সংকলনের সময় নির্ধারণ করার জন্য কঠোর চেষ্টা করুন। কোনও উল্লেখযোগ্য অপ্টিমাইজেশন স্তরে ইনলাইনিং প্রতিরোধ করার জন্য কেবলমাত্র পয়েন্টার ব্যবহার করা যথেষ্ট নয়; জিসিসি এমনকি অপ্টিমাইজেশন শূন্যে সরলীকরণও সম্পাদন করে!
কৌতূহলী

উত্তর:


153

ভার্চুয়াল ফাংশন কখনও কখনও অন্তর্ভুক্ত করা যেতে পারে। চমৎকার সি ++ ফ্যাক্সের একটি অংশ :

"কেবলমাত্র যখন ইনলাইন ভার্চুয়াল কলটি ইনলাইন করা যায় তখনই যখন কম্পাইলারটি ভার্চুয়াল ফাংশন কলটির লক্ষ্যবস্তু হয় এমন অবজেক্টটির" সঠিক শ্রেণি "জানে This কোনও অবজেক্টের রেফারেন্স either অর্থ, হয় কোনও স্থানীয় অবজেক্ট, একটি গ্লোবাল / স্ট্যাটিক অবজেক্ট, বা কোনও সংমিশ্রণের অভ্যন্তরে সম্পূর্ণরূপে অন্তর্ভুক্ত বস্তু সহ ""


7
সত্য, তবে এটি মনে রাখবেন যে সংকলক ইনলাইন স্পেসিফারটিকে উপেক্ষা করতে মুক্ত, এমনকি যদি সংকলনের সময় কলটি সমাধান করা যায় এবং ইনলাইন করা যায়।
তীক্ষ্ণতম

6
আমি যখন মনে করি যে ইনলাইনিং ঘটতে পারে তখন আমি অন্য পরিস্থিতিটি হ'ল যখন আপনি এই পদ্ধতিটি উদাহরণ হিসাবে কল করুন-> টেম্প :: আমার ভার্চুয়াল ফাংশন () - যেমন আহবান ভার্চুয়াল টেবিল রেজোলিউশন এড়িয়ে যায় এবং ফাংশনটি সমস্যা ছাড়াই ইনলাইন করা উচিত - কেন এবং যদি আপনি ' ডি এটি করতে চান অন্য বিষয় :)
আরএনআর

5
@RnR। 'এই->' থাকা দরকার নেই, কেবলমাত্র যোগ্য নাম ব্যবহার করা যথেষ্ট। এবং এই আচরণটি ডেস্ট্রাস্টার, কনস্ট্রাক্টর এবং সাধারণভাবে অ্যাসাইনমেন্ট অপারেটরগুলির জন্য ঘটে (আমার উত্তর দেখুন)।
রিচার্ড কর্ডেন

2
তীক্ষ্ণতম - সত্য, তবে এএফআইকি এটি সমস্ত ইনলাইন ফাংশনগুলির ক্ষেত্রে সত্য, কেবল ভার্চুয়াল ইনলাইন ফাংশনগুলি নয়।
কোলেন

2
অকার্যকর চ (কনস্টেট বেইজ এবং এলএইচএস, কনস্ট বেস এবং আরএইচএস)}} ------ ফাংশনটি বাস্তবায়নের সময় আপনি কখনই জানেন না যে রানটাইম অবধি কোন lhs এবং rhs ইঙ্গিত করে।
বায়ান হুয়াং

72

সি ++ 11 যোগ করেছে final। এটি স্বীকৃত উত্তরটি পরিবর্তন করে: অবজেক্টের সঠিক শ্রেণিটি সম্পর্কে জানা আর দরকার নেই, অবজেক্টটির কমপক্ষে শ্রেণীর ধরণ রয়েছে যেখানে ফাংশনটি চূড়ান্তভাবে ঘোষণা করা হয়েছিল তা জানা যথেষ্ট:

class A { 
  virtual void foo();
};
class B : public A {
  inline virtual void foo() final { } 
};
class C : public B
{
};

void bar(B const& b) {
  A const& a = b; // Allowed, every B is an A.
  a.foo(); // Call to B::foo() can be inlined, even if b is actually a class C.
}

এটি ভিএস 2017 এ ইনলাইন করতে সক্ষম ছিল না
যোলা

1
আমি মনে করি না এটি এইভাবে কাজ করে। A টাইপের A এর পয়েন্টার / রেফারেন্সের মাধ্যমে foo () এর প্রার্থনা কখনই প্রবেশ করা যায় না। বি.ফু () কল করার মাধ্যমে ইনলাইনিংয়ের অনুমতি দেওয়া উচিত। আপনি যদি না পরামর্শ দিয়ে থাকেন যে কম্পাইলারটি ইতিমধ্যে এটি টাইপ বি জানে কারণ এটি পূর্ববর্তী লাইনের বিষয়ে অবগত। তবে এটি সাধারণ ব্যবহার নয়।
জেফরি ফাউস্ট 10'18

উদাহরণস্বরূপ, বার এবং বেসের
জেফ্রি ফাস্ট

@ জেফ্রি ফাউস্ট তথ্য প্রচার না করার কোনও কারণ নেই, আছে কি? এবং iccলিঙ্ক অনুযায়ী এটি করতে বলে মনে হচ্ছে।
আলেক্সি রোমানভ

@ আলেকিরোমনভ কমপাইলারদের মানের বাইরে অপ্টিমাইজ করার স্বাধীনতা আছে এবং অবশ্যই আছে! উপরের মতো সাধারণ ক্ষেত্রে, সংকলকটি প্রকারটি জানতে পারে এবং এই অপটিমাইজেশনটি করতে পারে। বিষয়গুলি খুব কমই এটি সহজ, এবং সংকলনের সময় পলিমারফিক ভেরিয়েবলের আসল ধরণটি নির্ধারণ করতে সক্ষম হওয়া সাধারণ নয়। আমি মনে করি ওপি এই বিশেষ ক্ষেত্রে নয়, 'সাধারণভাবে' সম্পর্কে চিন্তা করে।
জেফ্রি ফাউস্ট

37

ভার্চুয়াল ফাংশনগুলির একটি বিভাগ রয়েছে যেখানে সেগুলি এখনও ইনলাইন করে রাখা বোধগম্য। নিম্নলিখিত বিষয় বিবেচনা করুন:

class Base {
public:
  inline virtual ~Base () { }
};

class Derived1 : public Base {
  inline virtual ~Derived1 () { } // Implicitly calls Base::~Base ();
};

class Derived2 : public Derived1 {
  inline virtual ~Derived2 () { } // Implicitly calls Derived1::~Derived1 ();
};

void foo (Base * base) {
  delete base;             // Virtual call
}

'বেস' মোছার জন্য কলটি, সঠিক ডেরিভেটেড ক্লাস ডেস্ট্রাক্টরকে কল করার জন্য একটি ভার্চুয়াল কল সম্পাদন করবে, এই কলটি অন্তর্ভুক্ত নয়। তবে যেহেতু প্রতিটি ডেস্ট্রাক্টর এটিকে পিতামাতার ডেস্ট্রাক্টর বলে (যা এই ক্ষেত্রে খালি), সংকলক ইনলাইন করতে পারে সেই কলগুলিকে , যেহেতু তারা বেস ক্লাস ফাংশনগুলিকে কার্যত কল করে না।

একই নীতিটি বেস বর্গ নির্মাণকারীদের জন্য বা কোনও ক্রিয়াকলাপের সেটের জন্য যেখানে অস্তিত্বের প্রয়োগটি বেস ক্লাসগুলির বাস্তবায়নকেও ডাকে।


23
একটি সচেতন হওয়া উচিত যদিও খালি ধনুর্বন্ধনী এর অর্থ সর্বদা বিনষ্টকারী কিছুই করেন না। ডেস্ট্রাক্টররা ক্লাসের প্রতিটি সদস্য অবজেক্টকে ডিফল্ট-ডেস্ট্রাস্ট করে, তাই আপনার যদি বেস ক্লাসে কয়েকটি ভেক্টর থাকে তবে সেই খালি ধনুর্বন্ধকের কাজটি বেশ কার্যকর হতে পারে!
ফিলিপ

14

আমি এমন সংকলকগুলি দেখেছি যেগুলি কোনও অন-ইনলাইন ফাংশন উপস্থিত না থাকলে কোনও ভি-টেবিল নির্গত করে না (এবং তারপরে একটি শিরোনামের পরিবর্তে একটি বাস্তবায়ন ফাইলে সংজ্ঞায়িত)। তারা ত্রুটি যেমন missing vtable-for-class-Aবা অন্য কিছু নিক্ষেপ করবে এবং আপনি যেমন নরকের মতো বিভ্রান্ত হবেন।

প্রকৃতপক্ষে, এটি স্ট্যান্ডার্ডের সাথে সামঞ্জস্যপূর্ণ নয়, তবে এটি হাইডারে না থাকলে কমপক্ষে একটি ভার্চুয়াল ফাংশন রাখার বিষয়টি বিবেচনা করুন (কেবলমাত্র ভার্চুয়াল ডেস্ট্রাক্টর), যাতে সংকলকটি সেই স্থানে শ্রেণীর জন্য একটি ভিটিবেল নির্গত করতে পারে। আমি জানি এটির কয়েকটি সংস্করণের সাথে ঘটেgcc

যেমনটি কেউ উল্লেখ করেছেন, ইনলাইন ভার্চুয়াল ফাংশনগুলি কখনও কখনও কোনও উপকার হতে পারে তবে আপনি যখন বস্তুর গতিশীল প্রকারটি জানেন না তখন বেশিরভাগ ক্ষেত্রেই আপনি এটি ব্যবহার করবেন , কারণ virtualএটি প্রথম স্থানে পুরো কারণ ছিল ।

সংকলকটি সম্পূর্ণ উপেক্ষা করতে পারে না inline। এটিতে ফাংশন-কলকে গতি বাড়ানো ছাড়াও অন্যান্য শব্দার্থবিজ্ঞান রয়েছে। দ্যঅন্তর্নিহিত ইনলাইন শ্রেণীর সংজ্ঞা যে পদ্ধতিতে আপনি হেডার মধ্যে সংজ্ঞা করা অনুমতি দেয়: শুধুমাত্র inlineফাংশন একটি লঙ্ঘন কোন নিয়ম ছাড়া পুরো প্রোগ্রাম সর্বত্র একাধিক বার সংজ্ঞায়িত করা যায়। শেষ পর্যন্ত, এটি এমনভাবে আচরণ করে যা আপনি পুরো প্রোগ্রামটিতে কেবল একবার এটি সংজ্ঞা দিয়েছিলেন, এমনকি আপনি একাধিকবার সংযুক্ত বিভিন্ন ফাইলগুলিতে শিরোনামটি একাধিকবার অন্তর্ভুক্ত করেছেন।


11

ঠিক আছে, প্রকৃতপক্ষে ভার্চুয়াল ফাংশনগুলি সর্বদা অন্তর্ভুক্ত করা যেতে পারে , যতক্ষণ তারা স্থিরভাবে একসাথে যুক্ত থাকে: মনে করুন আমাদের Base একটি ভার্চুয়াল ফাংশন Fএবং উত্পন্ন ক্লাস সহ একটি বিমূর্ত শ্রেণি রয়েছে Derived1এবং Derived2:

class Base {
  virtual void F() = 0;
};

class Derived1 : public Base {
  virtual void F();
};

class Derived2 : public Base {
  virtual void F();
};

একটি হাইপোটিটিকাল কল b->F();( bটাইপের সাথে Base*) স্পষ্টতই ভার্চুয়াল। তবে আপনি (বা সংকলক ...) এর মতো এটি আবারও লিখতে পারেন (ধরুন typeofএটি একটি সদৃশ typeidফাংশন যা কোনও মানটি ব্যবহার করে যা এটি ব্যবহার করে switch)

switch (typeof(b)) {
  case Derived1: b->Derived1::F(); break; // static, inlineable call
  case Derived2: b->Derived2::F(); break; // static, inlineable call
  case Base:     assert(!"pure virtual function call!");
  default:       b->F(); break; // virtual call (dyn-loaded code)
}

যদিও আমাদের এখনও আরটিটিআইয়ের প্রয়োজন রয়েছে typeof, মূলত নির্দেশটি স্ট্রিমের অভ্যন্তরে ভিটিবেল এম্বেড করে এবং জড়িত সমস্ত শ্রেণীর জন্য কলকে বিশেষীকরণের মাধ্যমে কলটি কার্যকরভাবে অন্তর্ভুক্ত করা যেতে পারে। এটি কেবলমাত্র কয়েকটি ক্লাস (বিশেষ করে বলুন Derived1) বিশেষায়নের মাধ্যমে সাধারণীকরণ করা যেতে পারে :

switch (typeof(b)) {
  case Derived1: b->Derived1::F(); break; // hot path
  default:       b->F(); break; // default virtual call, cold path
}

তারা কি কোনও সংকলক যা এটি করে? নাকি এটাই কি জল্পনা? দুঃখিত যদি আমি অতিরিক্ত সন্দেহবাদী হয়ে থাকি তবে উপরের বর্ণনায় আপনার সুরটি এর মতো শোনাচ্ছে - "তারা সম্পূর্ণরূপে এটি করতে পারে!", যা "কিছু সংকলক এটি করেন" এর চেয়ে আলাদা।
অ্যালেক্স মেইবার্গ

হ্যাঁ, গ্রেইল বহুকোষী ইনলাইনিং করে (সুলং হয়ে এলএলভিএম বিটকোডের জন্যও)
সিএএফএক্সএক্স

4

ভার্চুয়াল পদ্ধতিটিকে ইনলাইন চিহ্নিত করা, নিম্নলিখিত দুটি ক্ষেত্রে ভার্চুয়াল ফাংশনটিকে আরও অনুকূল করতে সহায়তা করে:


3

ইনলাইন সত্যিই কিছু করে না - এটি একটি ইঙ্গিত। সংকলক এটিকে উপেক্ষা করতে পারে বা এটি বাস্তবায়নটি দেখে এবং এই ধারণাটি পছন্দ করে যদি কোনও কল ইভেন্ট ইনলাইন ছাড়াই ইনলাইন করে । কোডের স্পষ্টতা যদি ঝুঁকিতে থাকে তবে ইনলাইনটি সরানো উচিত।


2
সংকলকগুলির জন্য যা কেবলমাত্র একক টিইউতে পরিচালিত হয়, তারা কেবল স্পষ্টভাবে ফাংশনটি ইনলাইন করতে পারে যেগুলির সংজ্ঞা রয়েছে। কোনও ফাংশন কেবলমাত্র একাধিক টিইউতে সংজ্ঞায়িত করা যায় যদি আপনি এটিকে ইনলাইন করেন। 'ইনলাইন' ইঙ্গিতের চেয়ে বেশি এবং এটি জি ++ / মেকফিল বিল্ডের জন্য নাটকীয় পারফরম্যান্স উন্নতি করতে পারে।
রিচার্ড কর্ডেন

3

ইনলাইনড ঘোষিত ভার্চুয়াল ফাংশনগুলি ইনজেক্টের মাধ্যমে ডাকলে এবং পয়েন্টার বা রেফারেন্সের মাধ্যমে ডাকা হলে উপেক্ষা করা হয়।


1

আধুনিক সংকলকগুলির সাথে এটি তাদের অন্তর্ভুক্ত করার কোনও ক্ষতি করবে না। কিছু প্রাচীন সংকলক / লিঙ্কার সংযুক্তি একাধিক ভ্যাটবেল তৈরি করেছে, তবে আমি বিশ্বাস করি না যে এটি আর একটি সমস্যা।


1

একটি সংকলক কেবল তখনই কোনও ফাংশনটি ইনলাইন করতে পারে যখন কলটি সংকলনের সময় উদ্বেগজনকভাবে সমাধান করা যায়।

ভার্চুয়াল ফাংশনগুলি যদিও রানটাইমের সময়ে সমাধান করা হয়, এবং তাই সংকলক কলটি ইনলাইন করতে পারে না, যেহেতু সংকলন টাইপ করে ডায়নামিক টাইপ (এবং সেইজন্য ফাংশন বাস্তবায়ন কল করতে হবে) নির্ধারণ করা যায় না।


1
আপনি যখন একই বা উত্পন্ন শ্রেণীর থেকে একটি বেস শ্রেণীর পদ্ধতি কল করেন তখন কলটি দ্ব্যর্থহীন এবং অ-ভার্চুয়াল হয়
তাত্পর্যপূর্ণ

1
@ শার্পতুথ: তবে তারপরে এটি একটি অ-ভার্চুয়াল ইনলাইন পদ্ধতি হবে। সংকলকটি আপনাকে জিজ্ঞাসা করবে না এমন ফাংশনগুলিকে ইনলাইন করতে পারে এবং কখন ইনলাইন করা উচিত বা না করা এটি সম্ভবত আরও ভাল knows এটা সিদ্ধান্ত নিতে দিন।
ডেভিড রদ্রিগেজ - ড্রিবিস

1
@ ড্রিবাস: হ্যাঁ, আমি ঠিক এটিই বলছি। আমি কেবলমাত্র এই বিবৃতিতে আপত্তি জানিয়েছিলাম যে ভার্চুয়াল শুল্কগুলি রানটাইমে সমাধান করা হয় - এটি কেবল তখনই সত্য যখন কলটি কার্যত করা হয়, সঠিক শ্রেণীর জন্য নয়।
তীক্ষ্ণতম

আমি বিশ্বাস করি যে এই বোকা। যে কোনও ফাংশন সর্বদা ইনলাইন করা যেতে পারে, এটি যত বড় হোক না কেন এটি ভার্চুয়াল কিনা। সংকলকটি কীভাবে রচিত হয়েছিল তা নির্ভর করে। আপনি যদি সম্মত না হন তবে আমি আশা করি যে আপনার সংকলকটি ইন-ইনলাইনড কোডও তৈরি করতে পারে না। এটি হ'ল: সংকলকটিতে কোডটি অন্তর্ভুক্ত থাকতে পারে যা রানটাইম পরীক্ষায় শর্তগুলির জন্য এটি সংকলন সময়ে সমাধান করতে পারে না। এটি ঠিক ঠিক এর মতোই আধুনিক সংকলকগণ স্থির মানগুলিকে সমাধান করতে পারে / সংকলন সময়ে সংখ্যার এক্সপ্রেশন হ্রাস করতে পারে। যদি কোনও ফাংশন / পদ্ধতিটি ইনলাইন করা না হয় তবে এর অর্থ এই নয় যে এটি প্রবেশ করা যাবে না।

1

যে ক্ষেত্রে ফাংশন কলটি দ্ব্যর্থহীন এবং ফাংশনটি ইনলাইনিংয়ের জন্য উপযুক্ত প্রার্থী, কম্পাইলার যেভাবেই কোড ইনলাইন করার জন্য যথেষ্ট স্মার্ট।

বাকি সময় "ইনলাইন ভার্চুয়াল" একটি বাজে কথা, এবং প্রকৃতপক্ষে কিছু সংকলকরা কোডটি সংকলন করে না।


জি ++ এর কোন সংস্করণ ইনলাইন ভার্চুয়ালগুলি সংকলন করবে না?
থমাস এল Holaday

হুঁ। আমি এখানে 4.1.1 এখন খুশি বলে মনে হচ্ছে। আমি প্রথমবার একটি 4.0.x ব্যবহার করে এই কোডবেসটিতে সমস্যার মুখোমুখি হয়েছি। অনুমান করুন আমার তথ্য পুরানো, সম্পাদিত।
চাঁদমাছ

0

ভার্চুয়াল ফাংশনগুলি তৈরি করা এবং তারপরে রেফারেন্স বা পয়েন্টারগুলির পরিবর্তে তাদেরকে বস্তুগুলিতে কল করার অর্থ নেই। স্কট মায়ার তাঁর "কার্যকর সি ++" বইয়ে পরামর্শ দিয়েছেন, উত্তরাধিকারসূত্রে প্রাপ্ত অ-ভার্চুয়াল ফাংশনটিকে কখনই নতুন করে সংজ্ঞা দেবেন না। এটি বোধগম্য, কারণ আপনি যখন একটি অ-ভার্চুয়াল ফাংশন দিয়ে একটি ক্লাস তৈরি করেন এবং কোনও উত্পন্ন ক্লাসে ফাংশনটিকে নতুনভাবে সংজ্ঞায়িত করেন, আপনি নিজে এটি সঠিকভাবে ব্যবহার করতে নিশ্চিত হতে পারেন তবে অন্যরা এটি সঠিকভাবে ব্যবহার করবেন তা আপনি নিশ্চিত হতে পারবেন না। এছাড়াও, আপনি পরবর্তী কোনও তারিখে এটিকে ভুলভাবে নিজেরাই ব্যবহার করতে পারেন। সুতরাং, যদি আপনি একটি বেস শ্রেণিতে কোনও ফাংশন করেন এবং আপনি এটি পুনঃনির্ধারণযোগ্য হতে চান তবে আপনার এটি ভার্চুয়াল করা উচিত। ভার্চুয়াল ফাংশনগুলি তৈরি করতে এবং তাদেরকে বস্তুগুলিতে কল করতে যদি এটি বোধগম্য হয় তবে সেগুলি ইনলাইন করাও বোধগম্য।


0

আসলে কিছু ক্ষেত্রে ভার্চুয়াল চূড়ান্ত ওভাররাইডে "ইনলাইন" যুক্ত করা আপনার কোডটি সংকলন না করে তুলতে পারে তাই মাঝে মাঝে কিছুটা পার্থক্য থাকে (কমপক্ষে VS2017s সংকলকের অধীনে)!

আসলে আমি ভিএস2017 এ একটি ভার্চুয়াল ইনলাইন ফাইনাল ওভাররাইড ফাংশনটি করছিলাম যা সংকলন এবং লিঙ্কে সি ++ 17 স্ট্যান্ডার্ড যুক্ত করেছিল এবং যখন আমি দুটি প্রকল্প ব্যবহার করছি তখন কোনও কারণে এটি ব্যর্থ হয়েছিল।

আমার একটি পরীক্ষার প্রকল্প এবং একটি বাস্তবায়ন ডিএলএল ছিল যা আমি ইউনিট পরীক্ষা করছি। পরীক্ষার প্রকল্পে আমার কাছে একটি "linker_includes.cpp" ফাইল রয়েছে যা প্রয়োজন অন্যান্য প্রকল্প থেকে * .cpp ফাইল অন্তর্ভুক্ত করে। আমি জানি ... আমি জানি যে আমি ডিএলএল থেকে অবজেক্ট ফাইলগুলি ব্যবহার করতে মিসবিল্ড সেট আপ করতে পারি, তবে দয়া করে মনে রাখবেন যে এটি একটি মাইক্রোসফ্ট নির্দিষ্ট সমাধান যখন সিপিপি ফাইলগুলি বিল্ড-সিস্টেমের সাথে সম্পর্কিত নয় এবং সংস্করণে আরও অনেক সহজ easier এক্সপিএল ফাইল এবং প্রকল্পের সেটিংস এবং এর চেয়ে সিপিপি ফাইল ...

মজার বিষয়টি হ'ল আমি পরীক্ষার প্রকল্প থেকে ক্রমাগত লিঙ্কার ত্রুটি পেয়ে যাচ্ছিলাম। এমনকি যদি আমি কপির পেস্ট দ্বারা অনুপস্থিত ফাংশনগুলির সংজ্ঞাটি অন্তর্ভুক্ত না করি তবে! খুব অদ্ভুত. অন্য প্রকল্পটি তৈরি করেছে এবং একটি প্রকল্পের রেফারেন্স চিহ্নিতকরণ ব্যতীত দুটির মধ্যে কোনও সংযোগ নেই তাই উভয়ই সর্বদা নির্মিত তা নিশ্চিত করার জন্য বিল্ড অর্ডার রয়েছে ...

আমি মনে করি এটি সংকলকটিতে এক ধরণের বাগ রয়েছে। সংকলকটিতে ভিএস2020 এর সাথে প্রেরণ করা আছে কিনা তা আমার কোনও ধারণা নেই, কারণ আমি একটি পুরানো সংস্করণ ব্যবহার করছি কারণ কিছু এসডিকে কেবল এটির সাথে সঠিকভাবে কাজ করে :-(

আমি কেবল যুক্ত করতে চেয়েছিলাম যে কেবল এগুলি ইনলাইন হিসাবে চিহ্নিত করার অর্থ কিছু অর্থ হতে পারে না, তবে এমনকি আপনার কোডটি কিছু বিরল পরিস্থিতিতে তৈরি নাও করতে পারে! এটি অদ্ভুত, তবুও জেনে রাখা ভাল।

পিএস: আমি যে কোডটিতে কাজ করছি তা কম্পিউটার গ্রাফিক সম্পর্কিত যা তাই আমি ইনলাইনিং পছন্দ করি এবং সে কারণেই আমি চূড়ান্ত এবং ইনলাইন উভয়ই ব্যবহার করি। আমি চূড়ান্ত স্পেসিফিকে রেখেছিলাম আশা করি যে রিলিজ বিল্ডটি ডিএলএল তৈরির জন্য যথেষ্ট চালাক, এমনকি আমাকে সরাসরি ইঙ্গিত না করেই ...

পিএস (লিনাক্স): আমি আশা করি যে নিয়মিতভাবে আমি এই ধরণের জিনিস ব্যবহার করতাম জিসিসি বা ঝনঝনিতেও ঘটবে না। আমি নিশ্চিত নই যে এই সমস্যাটি কোথা থেকে এসেছে ... আমি লিনাক্সে সি ++ করা বা কমপক্ষে কিছু জিসিসি দিয়ে পছন্দ করি তবে কখনও কখনও প্রকল্পের প্রয়োজনে আলাদা হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.