जवाबों:
आप आगे टाइप टाइप कर सकते हैं। लेकिन करने के लिए
typedef A B;
आपको पहले घोषणा करनी चाहिए A
:
class A;
typedef A B;
typedef
नाम एक जटिल बहुस्तरीय टेम्पलेट प्रकार आगे घोषणा का उपयोग करते हुए इस तरह जटिल और कठिन है। यह उल्लेख करने के लिए नहीं कि इसे डिफ़ॉल्ट टेम्पलेट तर्कों में छिपे कार्यान्वयन विवरण में गोताखोरी की आवश्यकता हो सकती है। और अंत समाधान एक लंबा और अपठनीय कोड है (विशेषकर जब प्रकार विभिन्न नामस्थानों से आते हैं) मूल प्रकार में बदलने के लिए बहुत प्रवण हैं।
आप में से मेरे जैसे उन लोगों के लिए, जो आगे देख रहे हैं कि एक सी-शैली की संरचना घोषित की गई है जिसे टाइप सीड का उपयोग करके परिभाषित किया गया था, कुछ सी ++ कोड में, मैंने एक समाधान पाया है जो निम्नानुसार है ...
// a.h
typedef struct _bah {
int a;
int b;
} bah;
// b.h
struct _bah;
typedef _bah bah;
class foo {
foo(bah * b);
foo(bah b);
bah * mBah;
};
// b.cpp
#include "b.h"
#include "a.h"
foo::foo(bah * b) {
mBah = b;
}
foo::foo(bah b) {
mBah = &b;
}
"Fwd एक टाइपराइड घोषित करने के लिए" आपको एक वर्ग या एक संरचना घोषित करने की आवश्यकता है और फिर आप टाइप किए गए प्रकार को टाइप कर सकते हैं। संकलक द्वारा एकाधिक समान टाइपडेफ स्वीकार्य हैं।
लंबा फार्म:
class MyClass;
typedef MyClass myclass_t;
संक्षिप्त रूप:
typedef class MyClass myclass_t;
C ++ में (लेकिन सादा सी नहीं), यह एक प्रकार का दो बार टाइप करने के लिए पूरी तरह से कानूनी है, इसलिए जब तक दोनों परिभाषाएं पूरी तरह से समान नहीं होती हैं:
// foo.h
struct A{};
typedef A *PA;
// bar.h
struct A; // forward declare A
typedef A *PA;
void func(PA x);
// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
A
बाद आप इस तरह से खेतों को कैसे परिभाषित करते हैं A
?
क्योंकि एक प्रकार की घोषणा करने के लिए, इसके आकार को जानना आवश्यक है। आप आगे एक सूचक को टाइप करने के लिए घोषित कर सकते हैं, या टाइप करने के लिए एक पॉइंटर को टाइप कर सकते हैं।
यदि आप वास्तव में चाहते हैं, तो आप नीचे दिए गए रखने के लिए pimpl मुहावरे का उपयोग कर सकते हैं। लेकिन अगर आप पॉइंटर के बजाय एक प्रकार का उपयोग करना चाहते हैं, तो संकलक को इसका आकार जानना होगा।
संपादित करें: j_random_hacker इस उत्तर के लिए एक महत्वपूर्ण योग्यता जोड़ता है, मूल रूप से आकार का उपयोग करने के लिए पता होना चाहिए , लेकिन एक आगे की घोषणा की जा सकती है यदि हमें केवल पता होना चाहिए कि मौजूद है , तो संकेत या संदर्भ बनाने के लिए। प्रकार। चूंकि ओपी ने कोड नहीं दिखाया था, लेकिन शिकायत की थी कि यह संकलन नहीं होगा, मैंने माना (शायद सही ढंग से) कि ओपी प्रकार का उपयोग करने की कोशिश कर रहा था , न कि केवल इसका संदर्भ लें।
पूर्ण एस के बजाय आगे की घोषणाओं का उपयोग करना #include
केवल तभी संभव है जब आप स्वयं (इस फ़ाइल के दायरे में) प्रकार का उपयोग करने का इरादा नहीं कर रहे हैं, लेकिन एक संकेतक या इसके संदर्भ में।
स्वयं प्रकार का उपयोग करने के लिए, संकलक को इसका आकार पता होना चाहिए - इसलिए इसकी पूर्ण घोषणा को देखना होगा - इसलिए पूर्ण #include
की आवश्यकता है।
हालाँकि, पॉइंटर या संदर्भ का आकार कंपाइलर के लिए जाना जाता है, चाहे पॉइंटर के आकार की परवाह किए बिना, इसलिए एक आगे की घोषणा पर्याप्त है - यह एक प्रकार का पहचानकर्ता नाम घोषित करता है।
दिलचस्प बात यह है कि जब पॉइंटर या संदर्भों class
या struct
प्रकारों का उपयोग किया जाता है , तो कंपाइलर अपूर्ण प्रकारों को संभाल सकता है जो आपको आगे पॉइंटर प्रकारों को घोषित करने की आवश्यकता को बचा सकता है:
// header.h
// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;
typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;
// Using the name without the class/struct specifier requires fwd. decl. the type itself.
class C; // fwd. decl. type
typedef C* CPtr; // no class/struct specifier
typedef C& CRef; // no class/struct specifier
struct D; // fwd. decl. type
typedef D* DPtr; // no class/struct specifier
typedef D& DRef; // no class/struct specifier
मेरे पास एक ही मुद्दा था, अलग-अलग फाइलों में कई टाइपडिफ के साथ गड़बड़ नहीं करना चाहता था, इसलिए मैंने इसे विरासत के साथ हल किया:
था:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
किया:
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
एक जादू की तरह काम किया। बेशक, मुझे किसी भी संदर्भ को बदलना पड़ा
BurstBoss::ParticleSystem
बस करने के लिए
ParticleSystem
मैंने इनहेरिटेंस और कंस्ट्रक्टर इनहेरिटेंस (?) के साथ typedef
( using
विशिष्ट होने के लिए) को प्रतिस्थापित किया ।
मूल
using CallStack = std::array<StackFrame, MAX_CALLSTACK_DEPTH>;
जगह ले ली
struct CallStack // Not a typedef to allow forward declaration.
: public std::array<StackFrame, MAX_CALLSTACK_DEPTH>
{
typedef std::array<StackFrame, MAX_CALLSTACK_DEPTH> Base;
using Base::Base;
};
इस तरह मैं आगे घोषणा करने में सक्षम था CallStack
:
class CallStack;
जैसा कि बिल कोट्सिया ने उल्लेख किया है, अपनी बात को निजी तौर पर टाइप करने के लिए रखने का एकमात्र उचित तरीका है, और आगे की घोषणा उन्हें विरासत के साथ करना है। यद्यपि आप इसे C ++ 11 के साथ थोड़ा अच्छा कर सकते हैं। इस पर विचार करो:
// LibraryPublicHeader.h
class Implementation;
class Library
{
...
private:
Implementation* impl;
};
// LibraryPrivateImplementation.cpp
// This annoyingly does not work:
//
// typedef std::shared_ptr<Foo> Implementation;
// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
// C++11 allows us to easily copy all the constructors.
using shared_ptr::shared_ptr;
};
@BillKotsias की तरह, मैंने विरासत का उपयोग किया, और इसने मेरे लिए काम किया।
मैंने इस गड़बड़ी को बदल दिया (जिसे मेरी घोषणा * .h में सभी बूस्टर हेडर की आवश्यकता थी)
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
typedef boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;
इस घोषणा में (* .h)
class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;
और कार्यान्वयन (*। cpp) था
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
class VanillaAccumulator : public
boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>>
{
};