শিরোনাম এবং সিপিপি ফাইলের মধ্যে শ্রেণি কোড পৃথক করা


169

আমি একটি সরল শ্রেণীর প্রয়োগকরণ এবং ডিক্লেয়ারেশন কোডকে কীভাবে একটি নতুন শিরোনাম এবং সিপিপি ফাইলে আলাদা করতে পারি সে সম্পর্কে আমি বিভ্রান্ত। উদাহরণস্বরূপ, আমি কীভাবে নিম্নলিখিত ক্লাসের কোড পৃথক করব?

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y)
  {
    gx = x;
    gy = y;
  }

  int getSum()
  {
    return gx + gy;
  }
};

12
মাত্র কয়েকটি মন্তব্য: কনস্ট্রাক্টরের সর্বদা শরীরে সদস্যদের স্থির করার পরিবর্তে একটি সূচনা তালিকা ব্যবহার করা উচিত। একটি ভাল এবং সাধারণ ব্যাখ্যা জন্য, দেখুন: কোড guru.com/forum/showthread.php?t=464084 এছাড়াও, সর্বনিম্ন বেশিরভাগ জায়গায়, সর্বসাধারণের ক্ষেত্র শীর্ষে থাকার রেওয়াজ রয়েছে। এটি কোনও কিছুই প্রভাব ফেলবে না, তবে যেহেতু সর্বজনীন ক্ষেত্রগুলি আপনার শ্রেণির নথি, তাই এটি শীর্ষে থাকা বোধগম্য।
মার্টিয়ার্ট

2
@ মার্টেরেট public:শীর্ষে সদস্য থাকা অনেক বেশি প্রভাব ফেলতে পারে , যদি ব্যবহারকারী তাদের পরামর্শ অনুযায়ী তাদের সরিয়ে নিয়ে যায় - তবে সদস্যদের মধ্যে নির্ভরতা অর্ডার করে থাকত এবং এখনও অবগত ছিল না যে সদস্যরা তাদের ঘোষণার ক্রমানুসারে আরম্ভ করা হয় ;-)
আন্ডারস্কোর_ডি

1
পছন্দ করেছেন তবে আবার, আমরা সবাই সতর্কতাগুলি ত্রুটি হিসাবে এবং সমস্ত সতর্কতা যা আমরা ভাবতে পারি তাই সংকলন করছি, তাই না? এটি আপনাকে অন্তত বলবে যে আপনি
এটিকে ঘৃণা

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

শীর্ষে সার্বজনীন ক্ষেত্র থাকা কেবল একটি শৈলী, যা অনেকেই আমার মতে দুর্ভাগ্যক্রমে গ্রহণ করেছেন। অতিরিক্তভাবে, @ মার্টারিট উল্লিখিত হিসাবে আপনাকে কিছু জিনিস মনে রাখা দরকার।
ভাসিলিস

উত্তর:


232

শ্রেণীর ঘোষণাটি হেডার ফাইলে যায়। এটি গুরুত্বপূর্ণ যে আপনি #ifndefঅন্তর্ভুক্ত রক্ষীদের যোগ করুন , বা আপনি যদি কোনও এমএস প্ল্যাটফর্মে থাকেন তবে আপনি এটিও ব্যবহার করতে পারেন #pragma once। এছাড়াও আমি ব্যক্তিগতটিকে বাদ দিয়েছি, ডিফল্টরূপে সি ++ শ্রেণীর সদস্যরা ব্যক্তিগত।

// A2DD.h
#ifndef A2DD_H
#define A2DD_H

class A2DD
{
  int gx;
  int gy;

public:
  A2DD(int x,int y);
  int getSum();

};

#endif

এবং বাস্তবায়ন সিপিপি ফাইলে যায়:

// A2DD.cpp
#include "A2DD.h"

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}

52
মনে রাখবেন যে আপনি যদি টেমপ্লেট প্রোগ্রামিং করছেন, তবে আপনাকে .h ফাইলে সবকিছু রাখতে হবে যাতে সংকলনের মুহুর্তে সংকলকটি সঠিক কোডটি ইনস্ট্যান্ট করবে।
লাইনলো

2
আপনার #ifndefশিরোনামে জিনিস আছে ?
ফেরেঙ্ক ডেক

4
সুতরাং এর অর্থ হ'ল যে সমস্ত ফাইল যা আপনার শিরোনামের ফাইলটি অন্তর্ভুক্ত করে তা ব্যক্তিগত সদস্যদের "দেখবে"। উদাহরণস্বরূপ, আপনি যদি একটি lib এবং এর শিরোনাম প্রকাশ করতে চান, আপনি শ্রেণীর ব্যক্তিগত সদস্যদের প্রদর্শন করতে হবে?
গৌথির

1
না, এখানে অসাধারণ বেসরকারী বাস্তবায়ন আইডিয়ামটি রয়েছে: en.wikedia.org/wiki/Opaque_pointer আপনি প্রয়োগের বিবরণটি গোপন করতে এটি ব্যবহার করতে পারেন।
পেরেক ডেক

3
এই শব্দটির সাথে মাইনর নিতপিক: "শ্রেণির ঘোষণাটি শিরোনামের ফাইলে যায়"। এটি প্রকৃতপক্ষে একটি ঘোষণা, তবে এটি একটি সংজ্ঞাও, তবে পূর্ববর্তীটিতে পূর্বেরটি অন্তর্ভুক্ত থাকায় আমি বরং বলব যে শ্রেণি সংজ্ঞাটি শিরোলেখ ফাইলটিতে যায়। অনুবাদ ইউনিটে আপনার সদস্য ফাংশনের সংজ্ঞা রয়েছে, শ্রেণির সংজ্ঞা নেই। আমি সম্মত, এটি একটি ছোট সম্পাদনা মূল্য হতে পারে?
lubgr

17

সাধারণভাবে আপনার .h এ শ্রেণীর ত্রুটি থাকে যা আপনার সমস্ত ডেটা এবং আপনার সমস্ত পদ্ধতির ঘোষণা। আপনার ক্ষেত্রে এটি পছন্দ করুন:

A2DD.h:

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y);    
  int getSum();
};

এবং তারপরে আপনার .cpp এ এই পদ্ধতিগুলির বাস্তবায়ন রয়েছে:

A2DD.cpp:

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}

7

যখন আপনি কেবল আপনার প্রকল্পটি ফাইলগুলিতে বিভক্ত করতে চান সেই ক্ষেত্রে গ্রহণযোগ্য উত্তরের প্রক্রিয়াটি প্রয়োজনীয় নয় এমন বিষয়ে বিস্তৃত ফ্যাশনে বিষয়টি গবেষণা করার সময় পাঠকদের এই প্রশ্নটির বিষয়ে হোঁচট খাওয়া গুরুত্বপূর্ণ। এটি কেবলমাত্র যখন আপনার একক শ্রেণীর একাধিক প্রয়োগ প্রয়োজন হয় needed যদি প্রতি ক্লাসে আপনার বাস্তবায়ন এক হয় তবে প্রতিটির জন্য কেবল একটি হেডার ফাইলই যথেষ্ট।

সুতরাং, গৃহীত উত্তরের উদাহরণ থেকে কেবল এই অংশটির প্রয়োজন:

#ifndef MYHEADER_H
#define MYHEADER_H

//Class goes here, full declaration AND implementation

#endif

# আইফ্যান্ডেফ ইত্যাদি প্রিপ্রসেসর সংজ্ঞা এটিকে একাধিকবার ব্যবহারের অনুমতি দেয়।

পুনশ্চ. আপনি যখন সি / সি ++ 'বোবা' তা বুঝতে পেরে বিষয়টি আরও স্পষ্ট হয়ে ওঠে এবং # অন্তর্ভুক্তটি কেবল "এই জায়গায় এই পাঠ্যটি ফেলে দিন" বলার উপায়।


"বিভক্ত" ফাইলগুলিতে রেখে আপনি কি এটি করতে পারবেন .cpp, বা .hকোড প্রতিষ্ঠানের এই পদ্ধতির জন্য কেবল "ভাল"?
বেনি জোবিগান

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

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

6

মূলত ফাংশন ঘোষণা / সংজ্ঞাগুলির একটি পরিবর্তিত বাক্য গঠন:

a2dd.h

class A2DD
{
private:
  int gx;
  int gy;

public:
  A2DD(int x,int y);

  int getSum();
};

a2dd.cpp

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}

5

A2DD.h

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y);

  int getSum();
};

A2DD.cpp

  A2DD::A2DD(int x,int y)
  {
    gx = x;
    gy = y;
  }

  int A2DD::getSum()
  {
    return gx + gy;
  }

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

এবং তারপরে, আপনি তার পরে শিরোনামের পরিবর্তে প্রয়োগের ক্ষেত্রে অন্যান্য শিরোনামের ফাইলগুলি অন্তর্ভুক্ত করতে পারেন। এটি গুরুত্বপূর্ণ কারণ আপনার শিরোলেখ ফাইলটিতে যে কোনও শিরোনাম অন্তর্ভুক্ত রয়েছে (যে উত্তরাধিকারসূত্রে) অন্য যে কোনও ফাইল যা আপনার শিরোনাম ফাইল অন্তর্ভুক্ত রয়েছে file


4

আপনি ঘোষণাপত্রটি হেডার ফাইলে রেখে দিন:

class A2DD
{
  private:
  int gx;
  int gy;

  public:
    A2DD(int x,int y); // leave the declarations here
    int getSum();
};

এবং বাস্তবায়ন ফাইলে সংজ্ঞা রাখুন।

A2DD::A2DD(int x,int y) // prefix the definitions with the class name
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}

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

নোট করুন যে টেমপ্লেটগুলির জন্য আপনাকে এগুলি সমস্ত শিরোনামে রাখতে হবে।


1
হেডার ফাইলটিতে ব্যক্তিগত সদস্যদের এবং ফাংশনগুলি প্রয়োগ করা বাস্তবায়নের বিশদটি ফাঁস বলে বিবেচিত হয় না?
জেসন

1
@ জেসন, সাজানো সেগুলি প্রয়োজনীয় বাস্তবায়নের বিশদ। উদাহরণস্বরূপ, আমাকে জানতে হবে একটি শ্রেণি স্ট্যাকের জন্য কত স্থান ব্যবহার করবে। অন্যান্য সংকলন ইউনিটের জন্য ফাংশন বাস্তবায়ন প্রয়োজনীয় নয়।
পল ড্রাগার

1

সাধারণত আপনি শিরোনাম ফাইলে কেবলমাত্র ঘোষণা এবং খুব স্বল্প ইনলাইন ফাংশন রাখেন:

এই ক্ষেত্রে:

class A {
 public:
  A(); // only declaration in the .h unless only a short initialization list is used.

  inline int GetA() const {
    return a_;
  }

  void DoSomethingCoplex(); // only declaration
  private:
   int a_;
 };

0

আমি আপনার উদাহরণটিকে খুব বেশি উল্লেখ করব না কারণ এটি একটি সাধারণ উত্তরের জন্য একেবারেই সহজ (উদাহরণস্বরূপ এতে টেম্পলেটড ফাংশনগুলি থাকে না, যা আপনাকে তাদের শিরোনামে প্রয়োগ করতে বাধ্য করে), আমি থাম্বের নিয়ম হিসাবে যা অনুসরণ করি তা হ'ল পিম্পল বাগ্ধারা

দ্রুত সংকলনের সময় এবং সিনট্যাকটিক চিনির সাথে সাথে এর বেশ কিছু সুবিধা রয়েছে:

class->member পরিবর্তে class.member

একমাত্র ত্রুটি হল অতিরিক্ত পয়েন্টার যা আপনি প্রদান করেন।

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