# Native Code > برنامه نویسی با C > برنامه نویسی با Borland C++‎ Builder > سوال: ارور در union بی نام.

## Ananas

سلام علیکم.
[BCC32 Error] Unit1.cpp(30): E2019 'TDWORD_4x:: :: :: ()' cannot be declared in an anonymous union
  Full parser context
    Unit1.cpp(24): class TDWORD_4x
    Unit1.cpp(26): class TDWORD_4x:: 
یعنی چی! این دیگه چه اروریه. لطفا یک روشی یا یک compiler directive یا همچین چیزی بگید تا از شر این ارور خلاص شم.
این کد رو می نویسم :

typedef struct TDWORD_2x
{
    TDWORD_2x() {};
    DWORD dw1, dw2;
} *PDWORD_2x;

typedef struct TDWORD_4x
{
    union
    {
        struct
        {
            TDWORD_2x DW_1, DW_2;
        };
        DWORD DWs[4];
    };
} *PDWORD_4x;

به قسمت :


        struct
        {
            TDWORD_2x DW_1, DW_2;
        };

 ایراد میگیره که بخاطر قسمت :
TDWORD_2x() {};
هست . با حذف قسمت سازنده ی ساختمان اول، درست میشه. تو  Visual Studio ایراد نمیگیره ولی تو C++‎‎Builder ایراد میگیره. فکر میکنم به خاطر تنظیمات کامپایلره لطفا راهنمایی کنید.

----------


## Ananas

اگه شما هم همچین مشکلی رو دارید بیخود زور نزنید بعید میدونم بشه. ولی یک راه حل مشابه استفاده از تابع هست :
typedef struct FLOAT2
{
public:
    FLOAT2() {};
    float x, y;
} * PFLOAT2;

typedef struct FLOAT4
{
public:
    float f[4];
    FLOAT2 & v1() { return *(FLOAT2 *)&f[0]; };
    FLOAT2 & v2() { return *(FLOAT2 *)&f[2]; };
} *PFLOAT4;

----------


## tdkhakpur

*خی شما بالا داخل ساختار تابعی به اسم TDWORD_2x ساختید و در پاییت خواستید یه ساختار بسازید اونم داخل union که این اجازه رو نمیده.
تابه رو کامنت بزنید مشکل حله.
*

----------


## Ananas

خیلی ممنون از توجهتون. مشاهده ها 190 تا تا الان هست. مطمئنم دوستان کم توجهی نمیکنن بلکه می خوان نظم سایت رو رعایت کنن و چیزی که مطمئن نیستن نگن. لااقل مثل دوستمون *tdkhakpur* که لطف کردن ، یه چیزی بنویسید که من فکر نکنم فقط دارم با خودم حرف نزنم.
البته کلا قسمت C++‎builder خلوته.
و اما :



> ایراد میگیره که بخاطر قسمت :
> 1
> TDWORD_2x() {};
> 
> 
> 
> 
> هست . با حذف قسمت سازنده ی ساختمان اول، درست میشه. تو  Visual Studio  ایراد نمیگیره ولی تو C++‎‎‎Builder ایراد میگیره. فکر میکنم به خاطر  تنظیمات کامپایلره لطفا راهنمایی کنید.


همونطور که عرض کردم می دونم مشکل از این قسمته! و سوال اینجاست که می خوام سازنده رو داشته باشم ضمن اینکه می خوام این ستختمان رو تو union هم بکار ببرم، چطور این دو تا رو در کنار هم داشته باشم؟. من نمی خوام constructor رو حذف کنم. یعنی از ساختمان های DirectX استفاده میکنم (چیزی که نوشتم فقط مثال بود تا مشکل رو بگم) که نمی تونم تغییرشون بدم و ضمنا می خوام داده های ساختمان های خودم رو در صورت لزوم به عنوان نوع های DirectX به توابع DirectX ارسال کنم. یعنی union رو می نویسم تا هر وقت لازم باشه به توابع d3dx ارسال کنم. از اون گذشته دوباره با دقت امتحان کردم دیدم تو Visual Studio هم همین ارور رو می ده و من در مورد vs اشتباه می کردم . تو سایت msdn هم ارورش رو پیدا کردم و بخاطر ضعف C++‎builder نیست چون ساختمان دارای سازنده هست که ممکنه هر کاری توش انجام بشه ولی داخل union این سازنده هیچ وقت نمی تونه صدا زده بشه چون که مشخص نیست کدوم سازنده (قسمت های مختلف union) باید استفاده بشه. پس منطقیه که ارور بده. ولی من فقط می خوایم از اون ساختمان اولیه فقط به عنوان یک بلوک از داده ها ی پشت سر هم استفاده کنم. پس اون تابعی که تو پست دوم نوشتم کاری که می خوام برام انجام میده.

----------


## tdkhakpur

> و سوال اینجاست که می خوام سازنده رو داشته باشم ضمن اینکه می خوام این ستختمان رو تو union هم بکار ببرم، چطور این دو تا رو در کنار هم داشته باشم؟.


اگه کامپایلر تون میتونه سازنده رو پشتیبانی کنه پس مشکل حله اشکال از برنامه شما در تعریف ساختار داخل union هست که بهش اسم ندادید و union نمیتونه میدان دید ساختار رو تعیین کنه تا همه داده های رو بصورت داده واحد در نظر بگیر داخل کدتان قسمت قزمز شده رو اضافه کنید مشکل حله.

typedef struct TDWORD_2x
{
    TDWORD_2x() {};
    DWORD dw1, dw2;
} *PDWORD_2x;

typedef struct TDWORD_4x
{
    union
    {
        struct *Union_St*
        {
            TDWORD_2x DW_1, DW_2;
        };
        DWORD DWs[4];
    };
} *PDWORD_4x;

سوتی مجهول بعد این همه برنامه نویسی .

----------


## Ananas

> اگه کامپایلر تون میتونه سازنده رو پشتیبانی کنه پس مشکل حله


من با سه تا برنامه اینو امتحان کردم، visual studio و C++‎builder و dev C++‎  4.9.9.2 تو هر سه ارور میده.
این راهی که می گید من چند دفعه با ترکیب های مختلف امتحان کرده بودم، نشد. لطفا یک بار کدی که نوشتید امتحان کنید. الان اصلا به DW_1 دسترسی ندارید! پس به چه درد می خوره؟
البته من الان به جوابم رسیدم (داخل union نمیشه از ساختمانی که دارای سازنده هست، استفاده کرد و راهش همون تابعی هست که با & نوشتم).
با تشکر.

----------


## tdkhakpur

> من با سه تا برنامه اینو امتحان کردم، visual studio و C++‎builder و dev C++‎  4.9.9.2 تو هر سه ارور میده.
> این راهی که می گید من چند دفعه با ترکیب های مختلف امتحان کرده بودم، نشد. لطفا یک بار کدی که نوشتید امتحان کنید. الان اصلا به DW_1 دسترسی ندارید! پس به چه درد می خوره؟
> البته من الان به جوابم رسیدم (داخل union نمیشه از ساختمانی که دارای سازنده هست، استفاده کرد و راهش همون تابعی هست که با & نوشتم).
> با تشکر.


اگه همانطور که میگید کامپایلرتون ورژن نچندان پایینی باشه جواب میده و باید سانزنده داخل union جواب بده 
در ضمن من کد شما رو تغییر ندادم فقط برای ساختار اسم نزاشته بودید و ایراد از اونجا بود.
یه بار دیگه اجراش کنید همونی هست که اشاره شد.
*پاورقی
مورد زیاد پیچیده ای نیست موفق باشید.*

----------


## Ananas

> اگه همانطور که میگید کامپایلرتون ورژن نچندان پایینی باشه جواب میده و باید سانزنده داخل union جواب بده


جواب نمیده. error اش هم تو لیست error ها موجوده : http://msdn.microsoft.com/en-us/library/43ae0055
همونطور که اونجا نوشته : A union member cannot have a default constructor.



> در ضمن من کد شما رو تغییر ندادم فقط برای ساختار اسم نزاشته بودید و ایراد از اونجا بود.


می فهمم. با این حال به احترام گفته ی شما چند بار دیگه هم امتحان کردم با اینکه قبلا هم امتحان کرده بودم و می دونستم.



> یه بار دیگه اجراش کنید همونی هست که اشاره شد.


عرض کردم که، وقتی به Union اسم می دیم اجرا میشه و ارور نمیده ولی وقتی می خوای از DW_1 یا DW_2 استفاده کنی به شکل '.' یا '->' اون وقت ارور میده. لطفا به نوشته هام دقت کنید. کدی که تغییر دادید وقتی کپی کردم اجرا شد و ایراد نگرفت ولی در واقع شما یک ساختار رو با این روش داخل union تعریف کردید نه یک متغیر. الان اگه همچین چیزی بنویسیم :

typedef struct TDWORD_2x
{
    //TDWORD_2x() {};
    DWORD dw1, dw2;
} *PDWORD_2x;

typedef struct TDWORD_4x
{
    union U
    {
        struct S
        {
            TDWORD_2x DW_1, DW_2;
        } s;
        DWORD DWs[4];
    } u;
} *PDWORD_4x;

(دقت کنید که سازنده رو حذف کردم) یه متغیر به اسم s (با حروف کوچیک) از این ساختار S (با حروف بزرگ) تعریف کردیم که میشه داخل برنامه به شکل :

    TDWORD_4x d;
    d.u.s.DW_1.dw1 = 0;

ازش استفاده کرد. البته باید به خود union هم اسم بدیم و در پی اون باید مثل ساختار، اینجا هم از union یک متغیر تعریف کنیم.
حالا اگه سازنده رو دوباره فعال کنیم، می بینیم که بازم ارور "استفاده از ساختاری با سازنده" رو میده.



> *مورد زیاد پیچیده ای نیست موفق باشید.*


اتفاقا پیچیدس، چون مورد رو دست کم می گیرید زیاد بهش دقت نمی کنید. یک بار، یک برنامه ی کامل (هم تعریف و هم یک مورد استفاده از ساختار تعریف شده) ازش بنویسید. اون وقت به همون نتیجه ای که من رسیدم میرسید.
ببخشیدا، قصد کلکل ندارم. شایدم من دارم اشتباه میکنم.

----------


## tdkhakpur

> چون مورد رو دست کم می گیرید زیاد بهش دقت نمی کنید. یک بار، یک برنامه ی  کامل (هم تعریف و هم یک مورد استفاده از ساختار تعریف شده) ازش بنویسید.  اون وقت به همون نتیجه ای که من رسیدم میرسید.


دست کم نمیگیریم البته نمیدانم برای چه منظوری این کار رو لازم دارید اما تا اونجایی که میدانم union برای تعریف خودش اول میره داده ها رو تنظیم میکنه بعد میره سراغ اجرا ولی در بالا قبل اینکه داده ها تنظیم بشه کد اجرا میشه و اینم یه نمونه خط قرمزی هست که کامپایر باید نشون بده.
در مورد اینکه چیکار باید کرد تا برنامه شما با تعریف ساختار آخر بره constructor ها رو اجرا کنه کار زیاد بزرگی نیست شما میتوانستید قانون union رو دور زده و از سازنده خود union کمک بگیرید مثل این.

typedef struct TDWORD_2x
{
    TDWORD_2x(){};
    DWORD dw1, dw2;
} *PDWORD_2x;

typedef struct TDWORD_4x
{
    union U
    {
         struct S
         {
             TDWORD_2x DW_1, DW_2;
         }*s;

         U() { s = new struct S[1];}
        ~U() { delete [] s; }

        DWORD DWs[4];
    } u;
} *PDWORD_4x;

و این شکلی هم استفاده کنید

TDWORD_4x d;
d.u.s->DW_1.dw1 = 0;

----------


## Ananas

بله. من همین روش رو هم امتحان کردم. ولی الان داده ها از یک جا شروع نمیشن! یعنی با تغییر یکی، اون یکی تغییر نمیکنه.
ببینید یک بار دیگه بهتر منظرم رو از انجام این کار بگم :
من یک سری ساختار از پیش تعریف شده به همراه توابع کار با اونها رو دارم (DirectX) حالا می خوام ساختمان ها و کلاسهایی رو از ترکیب این ساختار ها برای خودم به شکل سفارشی برای منظورهای مختلف بسازم که هر وقت لازم شد بتونم داده های کلاس خودم ر با توابع DirectX دستکاری کنم و به موازات اون از همین اطلاعات به عنوان آرایه و یا ساختار های تعریفی خودم استفاده کنم. و برای این کار بهترین روش استفاده از همچین عبارتهایی هست :
(FLOAT2 *)&f[0];
که تو پست دوم نوشتم. و خوب من می خواستم داخل کد نیام دائم این تبدیل رو انجام بدم و همه جا اینو بنویسم و می خواستم از union استفاده کنم که خودش اتوماتیک این کارو انجام بده، که دیدم امکانش نیست، تصمیم کرفتم از تابع :

    FLOAT2 & v2() { return *(FLOAT2 *)&f[2]; };

استفاده کنم که دقیقا همون کار رو برام انجام میده و اسراری ندارم که حتما به شکل یک union باشه. همون کد پست دوم رو کپی می کنم :

typedef struct FLOAT2
{
public:
    FLOAT2() {};
    float x, y;
} * PFLOAT2;

typedef struct FLOAT4
{
public:
    float f[4];
    FLOAT2 & v1() { return *(FLOAT2 *)&f[0]; };
    FLOAT2 & v2() { return *(FLOAT2 *)&f[2]; };
} *PFLOAT4;

من دیدم به جای اینکه حما به union فشار بیارم و گیر بدم بهتره که با نوشتن این توابع ها خیلی راحت به نتیجه دلخواه برسم. به قول معروف نمیشه به رادیکال دو زور شد تا آخر عمرمون هم که محاسبه کنیم تعداد اعشارهاش انتها نداره! پس بهتره عمرمون رو تلف نکنیم. استفاده از ساختاری با داشتن سازنده، داخل union امکان نداره (محدودیت زبان برنامه نویسی) پس باید با همچین توابعی کلکش بزنیم و اون چیزی رو که می خوایم از برنامه بگیریم. (استفاده از یک قسمت اطلاعات روی رم، به عنوان چند نوع ساختار متفاوت از نظر اسمی ولی مشابه از نظر نوع اطلاعات).

----------


## tdkhakpur

> من همین روش رو هم امتحان کردم. ولی الان داده ها از یک جا شروع نمیشن! یعنی با تغییر یکی، اون یکی تغییر نمیکنه.


اگه اشتباه نکنم منظورتون اینه که وقتی union تعرف میکنید وقتی داده های ساختار TDWORD_2xتغییر میکنه اون تغییرات داخل DWs[4] از union هم باید تغییر کنه.
اما به نظرم این روشی که قصد انجامش رو دارید اشتباهه اگه توضیحات union رو نگاه کنید اساسا union برای ایجاد یه بسته داده و نامگزاری اون بسته از داده به انواع مختلف متغییرهاست تا هر قسمتی از برنامه بتونه با داده های موجود در بسته union با اسم نوع متغییر خودش ارتباط برقرار کنه و نیازی به تبدیلات تکراری نداشته باشه.
اما اون بالا شما یک ساختار رو که دارای توابع(هر چند سازنده) هست رو به union دادید و در زیر اون یک آرایه از نوع دابل تعریف کردید و انتظار دارید تغییرات موجود در ساختار در این آرایه وارد بشه البته از لحاظ منطقی  داده ها وارد میشه اما اون نتیجه ای که  الان منظور شماست رو نخواهد داد.
در مورد روش دیگه شما , اصل مطلب دستم نیست اما میتوانید از روشهای دیگه به هدفتان برسید.

----------


## Ananas

> اگه اشتباه نکنم منظورتون اینه که وقتی union تعرف میکنید وقتی داده های  ساختار TDWORD_2xتغییر میکنه اون تغییرات داخل DWs[4] از union هم باید  تغییر کنه.





> اما به نظرم این روشی که قصد انجامش رو دارید اشتباهه اگه توضیحات union رو  نگاه کنید اساسا union برای ایجاد یه بسته داده و نامگزاری اون بسته از  داده به انواع مختلف متغییرهاست تا هر قسمتی از برنامه بتونه با داده های  موجود در بسته union با اسم نوع متغییر خودش ارتباط برقرار کنه و نیازی به  تبدیلات تکراری نداشته باشه.


این دو تا همدیگر رو نقض نمی کنن. union خاصیتش همینه که شما بایت ها رو به شکل های مختلف می تونید بنویسید و بخونید. این ساختاری که من تعریف کردم دقیقا دو تا DWORD رو داره پشت سر هم ذخیره میکنه و آرایه هم همینکار رو میکنه. پس DWORD اولی داخل ساختار همون بایت هایی رو مصرف میکنه که DWORD اولین عضو آرایه مصرف میکنه. پس باید یکی رو تغییر بدی اون یکی هم تغییر کنه. اصلا این یکی و اون یکی در کار نیست هر دو یک قسمت حافظه هستن من اصطلاحا این طور گفتم. یک باجه تلفن داخل شهر رو فرض کن، خوب هر کسی بخواد با از طریق اون باجه تلفن تماس بگیره باید از یک دستگاه تلفن واحد استفاده کنه که مشترک هست. حالا ما بیایم یک اشاره گر داخل union تعریف کنیم مثل روش شما دیگه این خاصیت از بین میره. اگه می خواستیم همچین کاری بکنیم نیازی به union نبود همونجا داخل struct مستقیما اشاره گر رو تعریف میکردیم. ببینید یک مثال دیگه : فرض کن یک انبار داریم که کلیدش دست چند نفره، حالا هر کدوم می تونن به دلخواه (روش دستیابی) خودشون داخل این انبار کالایی قرار بدن یا بردارن یا چیزی رو جبجا کنن (تغییر بدن، بنویسن یا بخونن). خوب طبیعیه که هر چی این یکی اضافه کنه اون یکی هم می تونه استفاده کنه. سایز انبار تغییر نکرده و همه ی شریک ها یک انبار با سایز مشخص (مشترک) در دسترسشونه. هر تغییری که هر کدوم از شریک ها بدن اون یکی هم تاثیر می گیره. مثل قصه ی سوراخ کردن کشتی توسط یک نفر که همه دارن از یک کشتی مشترک استفاده میکنن.

----------


## tdkhakpur

> این ساختاری که من تعریف کردم دقیقا دو تا DWORD رو داره پشت سر هم ذخیره  میکنه و آرایه هم همینکار رو میکنه. پس DWORD اولی داخل ساختار همون بایت  هایی رو مصرف میکنه که DWORD اولین عضو آرایه مصرف میکنه. پس باید یکی رو  تغییر بدی اون یکی هم تغییر کنه.


برداشتی که در این مورد دارید اشتباهه شما اونجا سازنده (تابع تعریف شده در ساختار) رو به حساب نمیارید به همین دلیل فکر میکنید فقط داده ها برای union اهمیت داره در صورتی که هر موردی که برای ساختار تعریف کنید چه داده باشه و چه تابع, جز داده های اطلاعاتی چیز دیگه ای نیست و union همه اونا رو مد نظر داره.
پس با این اوصاف نمیتونید بگید باید داده ها رو هم پوشی بشن.



> فرض کن یک انبار داریم که کلیدش دست چند نفره، حالا هر کدوم می تونن به  دلخواه (روش دستیابی) خودشون داخل این انبار کالایی قرار بدن یا بردارن یا  چیزی رو جبجا کنن (تغییر بدن، بنویسن یا بخونن). خوب طبیعیه که هر چی این  یکی اضافه کنه اون یکی هم می تونه استفاده کنه. سایز انبار تغییر نکرده و  همه ی شریک ها یک انبار با سایز مشخص (مشترک) در دسترسشونه. هر تغییری که  هر کدوم از شریک ها بدن اون یکی هم تاثیر می گیره. مثل قصه ی سوراخ کردن  کشتی توسط یک نفر که همه دارن از یک کشتی مشترک استفاده میکنن.


این همه مثال ها درسته اما اگه نوع قضیه فقط داده ها باشن نه اینکه توی ساختارتون تابع داشته باشید در صورتیکه که خود اون تابع هم میتونه یک سری داده های دیگه  و کارهای دیگه انجام داده باشه.

----------


## Ananas

خوب داریم به جاهای خوبی میرسیم. کم کم متوجه اختلاف نظرها میشیم.



> برداشتی که در این مورد دارید اشتباهه شما اونجا سازنده (تابع تعریف شده در  ساختار) رو به حساب نمیارید به همین دلیل فکر میکنید فقط داده ها برای  union اهمیت داره در صورتی که هر موردی که برای ساختار تعریف کنید چه داده  باشه و چه تابع, جز داده های اطلاعاتی چیز دیگه ای نیست و union همه اونا  رو مد نظر داره.
> پس با این اوصاف نمیتونید بگید باید داده ها رو هم پوشی بشن.


 اتفاقا من نظرم اینه که توابع جزئ اطلاعات هر نمونه از کلاس یا شی نیستن. ببینید شما یک دفعه یک تابع رو داخل یک ساختار تعریف می کنید و تو هر نمونه ای که از اون ساخته میشه این تابع می تونه فراخونی بشه. ولی در مورد متغیر ها و داده ها شما هر متغیری که داخل ساختار اضافه میکنید به سایز ساختارتون اضافه می کنید ولی در مورد تابع اینطور نیست. شما اگه 10 تا تابع هم که داخل ساختار داشته باشید بازم سایزش همونه که هیچ تابعی نداشته باشید. دلی فقط 10 تا char که هر کدوم 1 بایت هستن به ساختار اضافه کنید ، به سایز ساختار حداقل 10 بایت اضافه کردید.(گفتم حداقل چون اگه از pack (فشرده سازی) استفاده نکنید میتونه داخل ساختار فضای خالی حبس بشه به دلیل اینکه ممکنه ترتیب و اندازه و تعداد داده ها جوری باشه که سایز ساختار، توانی درست و مرتبی از 2 نباشه و مقدار اضافه برای هر نمونه از شی گرفته بشه). ولی ساختارهایی که من استفاده کردم تو این چند تا مثال همشون سازشون رند هست و میبینید که با استفاده از تابع مرجع (پست دوم) دارم همین کار رو به درستی و بدون هیچ ایرادی انجام می دم. الان اگه بخوایم مثلا یک متغیر رو که به اندازه ی 64 بیت روی حافظه فضا اشغال کرده رو به دو شکل (انواع مختلف داده ای) استفاده کنیم خیلی راحت با اشاره گر امکان پذیره. درسته؟ مثال :

double fd = 3.14159265358979L;
__int64 i64 = *(__int64 *)(&fd);

اینجا عدد اعشاری به عدد صحیح تبدیل نشده بلکه بیت های متغیر double تو __int64 ذخیره شده. تو union هم همینطور از ساختار ها به عنوان قسمتی از حافظه میشه استفاده کرد. این عمل مرسومی هست و تو زبانهای برنامه نویسی دیگه هم من دیدم کاربرد داره و استفاده میشه.



> این همه مثال ها درسته اما اگه نوع قضیه فقط داده ها باشن نه اینکه توی  ساختارتون تابع داشته باشید در صورتیکه که خود اون تابع هم میتونه یک سری  داده های دیگه  و کارهای دیگه انجام داده باشه.


یه موقع هست که مثلا تو کلاس یا ساختارمون از اشاره گرها و انواع متنوع استفاده کرده باشیم و یا از داده های private استفاده کرده باشیم (این یکی رو هنوز امتحان نکردم و مطمئن نیستم.) شاید به مشکل بر بخوریم تازه اونم اگه خودمون دقت نکنیم اشکال منطقی از دیدمون پنهان بشه ولی ساختاری که من تعریف کردم کاملا صاف و پوست کنده هست و کاملا میشه جایگزین یک آرایه بشه. حتی داخل ساختار  انواع مختلفی هم نداریم همشون یا FLOAT هستن یا همشون DWORD که 32 بیت و کاملا واضح هستن. با نظر شما در مورد سازنده موافقم اصلا همون اول هم دلیل ارور رو همین عرض کردم. ولی از نظر روش پیاده سازی این اشکال وجود داره چون تو مثال تابع مرجع (پست 2) می بینید که کاملا درست اجرا میشه.

----------


## tdkhakpur

ببینید از نظر اندازه شاید جواب بده اما از لحاظ منطق کدینگ و تفسیر کامپایلر قضیه انطوری نیست که بر روی کاغذ میاد من به شخصه خودم هنوزم که هنوز من از نحوه میدان یابی داده ها و توابع و ایجاد  خصوصی سازی در ساختارها و کلاسها توی سی رو سر در نیاوردم و وقتم روش نزاشتم که ببینم سی چطوری این کارا ها رو انجام میده.
در هر حالت هنوز هم مشکلتون رو ندونستم چیه اما اگه این دلایل باعث نمیشه که داده ها به درستی رو هم پوشی بشه یه دونه راه میمونه که اونم به تنظیمات کامپایلر شما ارتباط داره اگه شما در قسمت project option  قسمت تنظیمات دیتا رو تغییر داده باشید امکانش هست که data Alignment ترتیب داده های ساختار شما رو تحت تاثیر قرار داده باشه و اندازه رو بر اساس بلوکهایی 2 بایتی در نظر گرفته و به جای مثلا 4 بایت بر اساس محاسبه شما در هر چهار بایت دو بایت هدر رفته باشه و این هم میتونه داده های شما رو از همپوشی در ساختار و متعاقب ااون در union تحت تاثر قرار داده باشه.
یعنی مثلا اگه تو مثال زیر data Alignment چهار بایتی باشه و اندازه ساختار2  باشه اندازه  میشه 4 و اگه 4 بایتی باشه بازم 4 محاسبه میشه.

struct s
{
char b[2]
}

اگر قضیه چیزه دیگه هست یه کمی بگید مشکل کجاست و به چه دلیل این کار رو احتیاج دارید برای برنامه هست یا تحقیق؟
در موزد تحقیق همان مطالبی رو که ارسال کردید درسته و نمیشه به compiler و مستندات اون ایراد گرفت.

----------


## Ananas

> در هر حالت هنوز هم مشکلتون رو ندونستم چیه


مشلم که حل شده فقط داریم تبادل اطلاعات می کنیم. اما بیشتر توضیح می دم.



> ما اگه این دلایل باعث نمیشه که داده ها به درستی رو هم پوشی بشه یه دونه  راه میمونه که اونم به تنظیمات کامپایلر شما ارتباط داره اگه شما در قسمت  project option  قسمت تنظیمات دیتا رو تغییر داده باشید امکانش هست که data  Alignment ترتیب داده های ساختار شما رو تحت تاثیر قرار داده باشه و  اندازه رو بر اساس بلوکهایی 2 بایتی در نظر گرفته و  یه جای مثلا 4 بایت بر  اساس محاسبه شما در هر چهار باید هدر رفته باشه و این هم میتونه داده های  شما رو از همپوسی در ساختار و متعاقب ااون در union تحت تاثر قرار داده  باشه.
> یعنی مثلا اگه تو مثال زیر data Alignment  رو 2 بایت باشه اندازه ساختار میشه 4 و اگه 4 باشه بازم 4 محاسبه میشه.
> 1
> 2
> 3
> 4
> 5
> struct s
> {
> ...


درسته. با این قسمت مشکلی ندارم. البته من داخل کد از عبارت pragma pack برای مشخص کردن align در قسمت های مختلف کد استفاده میکنم. مثال :

#pragma pack(push, 4)
struct Point3D
{
public:
    float x, y, z;
};
#pragma pack(pop)

فکر میکنم به طور پیش فرض 4 باشه ولی من معمولا روی 1 (حد اقل) تنظیم میکنم.



> در موزد تحقیق همان مطالبی رو که ارسال کردید درسته و نمیشه به compiler و مستندات اون ایراد گرفت.


بله من این موضوع رو پذیرفتم و باهاش کنار اومدم. آخه منطقی هم نیست چند تا ساختار با سازنده های مختلف برای یک نمونه از شی همزمان موقع ایجادشدن فراخوانی بشن. پس کامپایلر داره درست عمل می کنه.



> اگر قضیه چیزه دیگه هست یه کمی بگید مشکل کجاست و به چه دلیل این کار رو احتیاج دارید برای برنامه هست یا تحقیق؟


تحقیق که نیست، برای برنامه های خودم هست. 
اما قضیه از این قراره :
تو DirectX و مشخصا Direct3D و D3DX (می دونید که برای کارهای گرافیکی و نمایش سریع و ساخت gamre استفاده میشه) ساختارها و توابع طوری هستن که اکثرا سخت افزاری انجام میشن (به دلیل نیاز به سرعت بالا و نمایش آنی). d3dx ساختارها و توابعی داره که برای کار با بردارهای 3 بعدی ریاضی و ماتریس ها تعریف شدن که اکثر توابع پر کاربرد و مهم اون سخت افزاری محاسبه میشن و نسبت به کد های دست نویس با C++‎‎ ، امتحان کردم تا حد 7 برابر سریع تر بوده. و این توابع معمولا با ارسال اشاره گری به ابتدای ساختار ها (بردارها و یا ماتریس ها) کار می کنن. بخاطر همین ساختارها کاملا استاندارد تعریف شدن و سایز مشخصی دارن و ترتیب داده ها هم مشخص هست. مثلا برای بردار سه بعدی معمولا ما با عبارت x , y, z  آشنا هستیم و راحت می تونیم ارتباط برقرار کنیم از طرفی هم برای عملیات ماتریسی و برداری خیلی جاها نیاز به استفاده از حلقه و دسترسی به داده ها از طریق اندیس داریم (یک مورد لزوم استفاده از union). البته این ساختار ها داخل d3dx تعریف شدن نیازی نیست دوباره تعریف بشن. مثلا یک ماتریس 4x4 رو در نظر بگیرید که از 16 تا عدد اعشاری 32 بیتی ساخته شده. هر 4 تا عدد، یک بعد رو مشخص میکنه. که برای بعد چهارم معمولا 0.0 و یا 1.0 استفاده میشه و فقط برای کارهای خاص کاربرد داره. حالا فرض کنید من می خوام بردار سوم از ماتریس (بردار سه بعدی جهت محور z ماتریس) رو نرمال سازی کنم (طولش رو برابر یک کنم، بردار رو یکه کنم) ، و از طرفی تابعی دارم در d3dx که با دریافت یک اشاره گر به ابتدای یک بردار سه بعدی ، این کار رو انجام میده. حالا من چطور باید این ناحیه از ماتریسم رو به این تابع ارسال کنم؟ مسلما نمی خوایم یه بردار جدا بسازیم بعد نرمال سازیش کنیم بعد کپی کنیم تو ماتریسمون (سرعت خیلی برامون مهمه). جواب : پس باید از طریق تبدیل اشاره گرها مستقیما داده های ماتریسمون رو به تابع بفرستیم. مثل تابعی که تو پست 2 نوشتم. خوب من میخواستم برای خوانایی کد از union استفاده کنم که نشد ولی با این تابع دقیقا چیزی که می خوام حاصل میشه فقط نوشته ها یکمی طولانی تر و شلوغ تر میشه.
و همینطور کارهایی ازین قبیل. شاید بخوام طول بردار فقط دو محور x, y رو بدست بیارم پس نیاز به باید اشاره گر ای به یک بردار 2 بعدی دارم. در واقع تو این نوع توابع من کافیه اشاره گری به ابتدای یک آرایه از اعداد اعشاری رو داشته باشم و به تابع ارسال کنم.

----------


## tdkhakpur

در هر حالت تحیلی سیستم دست شماست و خودتان بهتر میتونید در این ارتباط بحث کنید اما به نظر من اگه قصد نوشت برنامه های گرافیکی رو دارید مستقیما از داده پردازی خود directx استفاده کنید به صرفه تر باشه تا اینکه خودتون بشینید و این کارها رو انجام بدید.
حالا واسه چه کاری لازمش دارید؟یعنی برنامتون برای چه کاری هست؟

----------


## Ananas

> مستقیما از داده پردازی خود directx استفاده کنید به صرفه تر باشه تا اینکه خودتون بشینید و این کارها رو انجام بدید.


تا جایی که بشه همین کار رو میکنم ولی مسلما روال های DirectX محدود هستن و بالاخره نیاز هست که بعضی جاها خودمون کد بنویسیم. البته با ترکیب توابع DirectX . مثلا ضرب ماتریسی و یا یافتن معکوس ماتریس و ضرب بردار در ماتریس. اینها عملیات مهم ریاضیات سه بعدی هستن.



> حالا واسه چه کاری لازمش دارید؟یعنی برنامتون برای چه کاری هست؟


شبیه سازی سه بعدی محیط های مجازی. شایدم یک روز بازی سازی. این برنامه رو با دلفی نوشته بودم که الان منتقلش کردم به C++‎ و دارم اونو ارتقاء می دم. کار خودمه سفارش سازمان و شرکتی نیست. نمونه هایی که با دلفی ساختم رو هم می تونید ببینید :
http://www.forum.khoramsoft.com/thread-244.html
و
http://www.forum.khoramsoft.com/thread-425.html
البته یکمی قدیمی و ساده هستن.
کار اصلیم هم طراحی سه بعدی و انیمیشن هست و این برنامه مربوط به این زمینه ست. کلا برنامه نویسی رو هم با برنامه نویسی سه بعدی شروع کردم از اسکریپت نویسی مکس شروع شد تا به اینجا رسید. (بیشتر خودم رو جز هنرمندها می دونم تا برنامه نویس ها)

----------


## tdkhakpur

> کار اصلیم هم طراحی سه بعدی و انیمیشن هست و این برنامه مربوط به این زمینه  ست. کلا برنامه نویسی رو هم با برنامه نویسی سه بعدی شروع کردم از اسکریپت  نویسی مکس شروع شد تا به اینجا رسید. (بیشتر خودم رو جز هنرمندها می دونم  تا برنامه نویس ها)


برنامه هات رو دیدیم اما اگه بخای از طریق برنامه نویسی و native بازی سازی انجام بدی خیلی عقب میمونی به نظرم از برنامه های اماده هم بتونی استفاده کنی بهتره.
اما در کل اگه هدفتان بازی سازی و اوج گیری در این زمینه هست در زمینه بازی های ویدئو گیم (video game) بصورت برنامه Natvie بنویسی سریعتر به نتیجه میرسی.
مثل بازی mad dog یا tom cat.
در این زمینه هم این میتونه کمکتون کنه.

----------


## Ananas

هدف من بازی سازی نیست وگرنه میرفتم سراغ موتوهای بازی سازی.
من برنامه نویسی رو دوست دارم همینطور گرافیک سه بعدی و نوشتن برنامه ای که با زحمت بیشتر همراهه ولی قدرت برنامه نویسی بیشتری نسبت به یه ابزار آماده داره برام شیرین تره. موتورهای بازی سازی با DirectX و OpenGL ساخته میشن و هدفشون ساخت بازیه ولی استفاده ی مستقیم از DirectX می تونه به یک برنامه ی و ابزار سه بعدی هم برسه. مثل 3DsMax و یا ZBrush . البته من نمی خوام 3DsMax بسازم ولی می تونم ابزارهای کمکی لازم رو بسازم و خیلی کارهای دیگه که یک برنامه نویس با DirectX می تونه انجام بده ولی یه بازی ساز با موتور بازیش نمی تونه انجام بده. یکی از موارد استفادش می تونه ساخت بازی باشه که من خیلی علاقه ندارم.

----------


## Ananas

به طور اتفاقی تو آدرس زیر خوندم که تو C++‎‎‎‎11 میشه از ساختمانی که سازنده داشته باشه تو union استفاده کرد :
http://en.wikipedia.org/wiki/C%2B%2B11


*Unrestricted unions*

 In C++‎‎‎‎03, there are restrictions on what types of objects can be members of a union. For example, unions cannot contain any objects that define a non-trivial constructor. C++‎‎‎‎11 lifts some of these restrictions.[3]
 This is a simple example of a union permitted in C++‎‎‎‎:
//for placement new
#include <new>

struct Point  {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};
union U {
    int z;
    double w;
    Point p;  // Illegal in C++‎03; point has a non-trivial constructor.  However, this is legal in C++‎11.
    U() { new( &p ) Point(); } // No nontrivial member functions are implicitly defined for a union;
                               // if required they are instead deleted to force a manual definition.
};


 The changes will not break any existing code since they only relax current rules.

----------

