-
تعداد ارسال ها
97 -
تاریخ عضویت
-
روز های برد
25
پست ها ارسال شده توسط قاسم رمضانی منش
-
-
درود و خستهنباشید به دوستان؛
میخواهم حالتی را مانند RadioButton که فقط میتوان «یکی از چندتا» را انتخاب کرد را در دکمههایی که خودم نوشتهام پیاده کنم، در حالت عادی به اینصورت عمل کردهام و خب مشخصاً راهحل خوبی نیست استفاده از تابع ()fundOutAndTurnOnButtonLight؛ به چه روشی میتوان بهتر عمل کرد ؟
main.qml
ApplicationWindow { id: root; visible: true width: 640; height: 480 color: "gray" function findOutAndTurnOnButtonLight(id){ switch(id){ case pageOne: pageTwo.isSelected = false pageThree.isSelected = false break case pageTwo: pageOne.isSelected = false pageThree.isSelected = false break case pageThree: pageOne.isSelected = false pageTwo.isSelected = false break } id.isSelected = true } Row{ id: kepper anchors.centerIn: parent spacing: 20 MyRec{ id: pageOne onButtonClicked: findOutAndTurnOnButtonLight(pageOne) } MyRec{ id: pageTwo onButtonClicked: findOutAndTurnOnButtonLight(pageTwo) } MyRec{ id: pageThree onButtonClicked: findOutAndTurnOnButtonLight(pageThree) } } }
و کامپوننت MyRec که در فایل MyRec.qml میباشد :
Item { id: root width: 100; height: 100 property bool isSelected : false signal buttonClicked() Rectangle{ id: myButton anchors.fill: parent color: "red" width: parent.width / 4 height: parent.height / 4 } Rectangle{ id: bar anchors{ bottom: myButton.bottom horizontalCenter: myButton.horizontalCenter } color: "blue" width: myButton.width / 2 height: 5 visible: isSelected } MouseArea{ id: clickableArea anchors.fill: myButton onClicked: buttonClicked() } states:[ State{ name: "entered" when: clickableArea.pressed PropertyChanges{ target: myButton color: "yellow" } } ] }
-
درود و خستهنباشید به دوستان؛
در مستندات RadioButtonStyle مثالی به اینصورت زده شده :
RadioButton { text: "Radio Button" style: RadioButtonStyle { indicator: Rectangle { implicitWidth: 16 implicitHeight: 16 ... } ... } ... }
امّا RadioButton خاصیّتی تحت عنوان style ندارد، آیا این مثال اشتباه است ؟ و چگونه میتوان از RadioButtonStyle استفاده کرد ؟
این مورد دربارهٔ CheckBoxStyle نیز صدق میکند.
ویرایش:
باتوجه به مستندات :
Import Statement: import QtQuick.Controls.Styles 1.4 Since: Qt 5.1 قابلیّت style در ویرایش 1.4 از ماژول QtQuick.Controls.Styles موجود میباشد، و پس از import کردن آن خطا رفع میشود. آیا اضافه کردن نسخهٔ 1.4 و 2.13 تداخلی به وجود میآورد ؟
- 1
-
درود و خستهنباشید به دوستان؛
درحال طراحی یک رابطکابریساده بودهام که خواستم قسمت رنگآمیزی Itemها و Fontها و ... به راحتی قابل تغییر و برنامهریزی باشد. اینکار را با استفاده از یک فایل QML جدا به اسم Style.qml به شکل زیر انجام دادم :
pragma Singleton import QtQuick 2.13 Item { property int textinputTextSize : 22 property color transparent : "transparent" property color bluredColor : "#5AAFAAAA" property int tabBarWidth : 50 property int tabBarHeight : 75 property int tabBarIconSize : 44 property int tabBarTextSize : 20 property color tabBarIconColor: "#81D8DE" property color tabBarTextColor: "#059EAB" property color tabBarBackColor: "#0571AB" property alias sahelRegular : sahel_font.name property alias fontAwesome : font_awesome.name FontLoader{ id: sahel_font source: "qrc:/assets/fonts/sahel/Sahel-FD-WOL.ttf" } FontLoader{ id: font_awesome source: "qrc:/assets/fonts/awesome/fontawesome-regular.ttf" } property color mainpageColor : "#E3F2FD" property color mainpageToolbarColor : bluredColor }
آیا این روش بهینه و درست است ؟ و یا راه بهتری هم وجود دارد ؟
- 1
-
درود بر شما؛
برای اینکار میتوانید شما از QScrollArea استفاده کنید. این کلاس یک منطقهٔنمایش Widgetها و یک QScrollBar را به شما میدهد، و شئ را که میخواهید Scroll کنید را باید به عنوان Child Widget به آن معرفی کنید. برای مثال :
#include <QApplication> #include <QDialog> #include <QGroupBox> #include <QList> #include <QScrollArea> #include <QTextEdit> #include <QVBoxLayout> int main(int argc, char** argv) { QApplication application(argc, argv); QDialog dialog; QVBoxLayout layout; QScrollArea scroll(&dialog); QGroupBox groupedArea; QList<QTextEdit*> widgets; for (int i {}; i < 20; ++i) { widgets.append(new QTextEdit); layout.addWidget(widgets.at(i)); } scroll.setWidget(&groupedArea); scroll.setWidgetResizable(true); groupedArea.setLayout(&layout); dialog.show(); return application.exec(); }
دقّت کنید که باید حتماً تابع setWidgetResizable را با مقدار true برای تغییر اندازهٔ مناسب Widget فراخوانی کنید.
خروجی حاصل از کد بالا :
با تشکر از آقایرضوی.
- 2
- 2
-
@nabegheh95 درود بر شما؛
در در 9 مرداد 1398 در 14:06، nabegheh95 گفته است :من سالهاست تجربه کار با ویژوال استودیوC++ رو دارم ولی به تازگی میخوام شروع کنم Qt را یا بگیرم.
لازم به ذکر بود که، برنامهٔ Microsoft Visual Studio یک IDE توسعه داده شده توسط شرکت Microsoft میباشد. و برای توسعهٔ هرچه بهتر برنامههای سیستمعامل Windows تحت Microsoft .Net میباشد. درواقع شما با کامپایلر Microsoft Visual C++.Net کارکردید.
برای فریمورک Qt هم یک IDE بسیارعالی وجود دارد که سرعت توسعهٔ نرمافزار با استفاده از این فریمورک را افزایش میدهد، پس پیشنهاد میکنم به جای استفاده از آن افزونه مستقیم از این IDE استفاده کنید چرا که یک IDE بسیار خوب نیز برای ++C\C میباشد.
تنها پیشنهاد میشود که در سیستمعامل Microsoft Windows از کامپایلر Microsoft Visual C++.Net استفاده کنید، این کامپایلر برای سیستمعامل خود به خوبی عمل میکند. هرچند که باید حواستان به تنبلیهای مایکروسافت باشد مواردی مثل مورد زیر اصلاً پیادهسازی نشدهاند:
void char_exception() throw(int){ throw 'x'; } int main(void){ try{ char_exception(); } catch (...){ std::cout << "Caught it." << std::endl; } return 0; }
در در 9 مرداد 1398 در 15:43، nabegheh95 گفته است :چون خیلی تازه شروع کردم به یادگیری Qt، بعضی جاها مبهم هست برام .
فریمورک Qt یک مجموعهٔ عظیم از کتابخانهها میباشد، که تماماً نیز در اینسایت مستند شدهاند. برای رفع ابهامات کافی است که مستندات را به دقّت مطالعه و نمونههای نوشته شده را بررسی و امتحان کنید.
در در 9 مرداد 1398 در 15:43، nabegheh95 گفته است :ولی به طور کلی فهمیدم که برای اجرایی شدن برنامه نهایی در هر سیستم عامل
اجرا شدن یک فایل، بسته به کرنل یک سیستمعامل و نحوهٔ پیادهسازی آن میباشد. پس مسلماً ساختاری که در کرنل Windows NT به عنوان فایل اجرایی شناخته شده است، در کرنل Linux قابل قبول نیست. برای اطلاعات بیشتر درمورد این ساختارها میتوانید ساختار PE و ELF را بررسی کنید.
در در 9 مرداد 1398 در 15:43، nabegheh95 گفته است :و همیشه سعی براین داشته باشم که فقط و فقط از توابع و apiهای خود Qt استفاده کنم
در حالت ایدهآل، بلی باید تلاش داشتهباشید که از APIهایی که Qt فراهم میکند استفاده کنید، امّا همیشه این کار شدنی نیست. شما همیشه نیازی به استفاده از Qt ندارید و ممکن است قابلیّتی در یک سیستمعامل نیاز داشتهباشید که مشابه آن در یک سیستمعامل دیگر متفاوت هست. برای مثال :
این سورس Telegram/ThirdParty/minizip/ioapi.c هست، ببینید به چه صورت در خطهای ۱۳ و ۱۷ و ۲۲ بسته به سیستمعامل مقصد مشخص کردهاست که چه توابعی باید کامپایل شوند. با این روش شما درحالی که از قابلیّت خاص یک سیستمعامل استفاده کردید ولی برنامهٔ شما Cross-Platform میباشد.
پیشنهاد میکنم کتاب «++API Design For C» نوشتهٔ آقای «Martin Reddy» را مطالعه کنید.
- 1
-
@Alireza4 درود؛
اینکه چه کاری انجام بدهید و به کدام راه برید، تماماً بستگی به خودتان دارد. پیشنهاد میکنم که قشنگ درمورد کاری که میخواهید انجام بدید تحقیق کنید :
- هدفتان از برنامهنویسی چیست ؟
- چقدر حوصلهٔ یادگیری مطالب را دارید ؟
- چقد دید سیستمی به برنامهنویسی دارید ؟
و ..، این مطلب را حتماً مطالعه کنید : کدام زبان برنامهنویسی را انتخاب کنم ؟ ، در این مقاله توضیحات لازم داده شده که بتونید خودتان تصمیم بر انتخاب زبان بگیرید. چرا که باید بدونید «درستهکه زبان سیپلاسپلاس قدرت زیادی داره» امّا باید بدونید که هرچیز خوبی بالاخره هزینهای هم داره و یادیگری کار کردن با این زبان به ششماه تموم نمیشه، برای اینکه دراینباره هم بیشتر اطلاعات کسب کنید مقالهٔ چرا و چگونه باید ++C را یادبگیریم ؟ ، شاید اصلاً چیزی نبود که شما فکر میکردید.
- 1
-
@MahdiGameMaker خطای «
دوباره پاک کردم پکیج ها رو و بعد نصب کردن باز هم ارور میده
»، ارور خوبی نمیباشد که ما نیز راهنماییای برای آن بکنیم. لطفاً یک لاگ با اطلاعات کافی (از طریق یک سرویس paste) ارائه بدید. -
سلام؛
خوشآمدید، لطفاً ده-دقیقه وقت بگذارید و اسناد زیر را جهت فعالیت در انجمن مطالعه بکنید :
در 5 ساعت قبل، MahdiGameMaker گفته است :نظرتان درمورد گنو/لینوکس چیست ؟ میخواهم کار با این سیستمعامل را شروع کنم، پیشنهادتان چیست ؟
سیستمعامل گنو/لینوکس، یک سیستمعامل آزاد - متنباز میباشد، که میتوانید به رایگان آن را دریافت و استفاده کنید :
نسخههای متعدد و زیادی از سیستمعاملهای گنو بر پایه کرنل لینوکس موجود میباشد که میتوانید هرکدام را به رایگان دریافت و استفاده بکنید :
جهت شروع آشنایی کار با این سیستمعاملها میتوانید از این دورهٔ آموزشی آقایمیرمیرانی شروع کنید :
در 5 ساعت قبل، MahdiGameMaker گفته است :اگر بخوام برم سراغ گنو/لینوکس باید دوباره کل
SDK
وNDK
وJDK
برای لینوکس دانلود کنم؟نیازی به بارگیری
SDK
وNDK
دوباره نیست، ولی برایJDK
بسیار بهتر میباشد که از طریق مدیربستهٔ توزیعتان اقدام به نصب آن کنید که اختلالی پیش نیاید. مطمئن شوید که این سند را نیز مطالعه کردید :- 1
-
در در 10 اردیبهشت 1398 در 10:04، Saman گفته است :من component WebEngine رو فعال کردم و QT += webview رو هم به فایل pro. اضافه کردم
سلام؛
مطمئن بشید که از نسخهٔ درست استفاده میکنید و اینکه این ماژول برای شما ساخته (بیلد) شده باشد؛ درغیراینصورت باید خودتان بسازید. اگر میخواید از دلمتن مقداری را بیرون بکشید بهترینکار این است که از QRegExp استفاده کنید.
-
سلام؛ بد نبود اگر نیَّت شما توسعهٔنرمافزارهای-اندروید بوده، از همان فناوری
QtQuick
استفاده میکردید.خب، برای آشنا شدن به مباحث و روش استفاده از Layoutها تنها راه ایناست که از همان پیوندیکه آقایاسدزاده دادند :
https://doc.qt.io/qt-5/layout.html
شروع کنید و مطالعهکنید، خوشبختانه اینبخشهم دارای مثالهای خوبی هست که میتونید با تمرین و تستوخطاهایی نتایج خوبی بگیرید. کافیهکه کاربرد هر Layout را متوجه شده و بدانید که در کجا باید استفاده کنید.
قطعه ویدئوهایی هم داخل youtude موجود میباشد که دیدنش بدنیست :).
- 1
-
سلام؛
این سوأل شما بسیار بسیار کلّی هست ! ، تا قسمت نوشتن برنامهٔخود که مرتبط به زبانبرنامهنویسی سیپلاسپلاس هست. ولی قسمت کامپایل و اجرای آن برنامه به عهدهٔ سیستمعامل شماست؛ بهتر بود که ذکر کنید از چه سیستمعاملی و چه نسخهای استفاده میکنید. حال بنده به صورت کلّی توضیحاتی میدهم امیدوارم مفید باشد :
- درصورتیکه از سیستمعاملهای
GNU/Linux
استفاده میکنید، شما باید مستندات دسکتاپ خودتان را بررسی کنید هر دسکتاپی که استفاده میکنید بنا به قواعد خودش فایلها/دستوراتی را در شروع دسکتاپ اجرا میکند. امّا اگر دسکتاپی ندارید ولی ازX
استفاده میکنید، بهتر است یک فایل.desktop
درست کنید و آن را در یکی از این مسیرها قرار بدهید :User :
~/.config/autostart
SystemWide :
/etc/xdg/autostart
نمونههای از قبل نوشته شدهٔ فایلهای
.desktop
را میتوانید در این آدرس پیدا کنید و یا یکی را خودتان بنویسید :User :
~/.local/share/applications
SystemWide :
/usr/share/applications
اگر از مدیرپنجرههایی مثل
i3wm
یاawesome
استفاده میکنید، میدانید که اینها فایلهای پیکربندی مختص به خود دارند که در آنها نیز میتوانید دستورات اجرایی خودتان را قرار بدید.- درصورتیکه از سیستمعامل
Mac OS
استفاده میکنید، به این لینک مراجعه کنید.- درصورتیکه از نرمافزار مایکروسافتویندوز استفاده میکنید، منوی
Start
را باز کرده و ابزارRun
را اجرا کنید - میتوانید اینکار را با زدن دکمههایWinKey + R
خلاصهکنید - و بعد عبارت:shell:startup
را وارد کنید، پنجرهٔ
Windows Explorer
باز میشود، هر فایلی که در آن دایرکتوری قرار بدهید در هنگامLogin User
اجرا میشود.- 1
- 1
-
سلام؛
میتوانید از
QKeyEvent
استفاده کنید، امّا این نیازمندgui
است.برای محیطمتنی میتوانید خود یک کلاس برای شناسایی کلید زده شده بنویسید و آن را در یک
QThread
اجرا کنید تا زمانی که کلید مورد نظر شناسایی شد عملی که نیاز دارید انجام شود. -
سلام ؛
Container :
این اسامیای که اسم بردید. تماماً Continer هستند. و وظیفه نگهداری دادههارا دارند. برای اینکه برنامهنویس دستش باز باشه در مدیریت دادهها در زبان برنامهنویسی سیپلاسپلاس میتونید از این کانتینرها در جهت نگهداری دادههاتون استفاده کنید. که استفاده از توابع و کلاسهای موجود در هدرفایل algorithm در کنار این کانتینرها پیشنهاد میشود و میتواند قدرت کنترل بیشتری به برنامهنویسی بر روی دادههای خود بدهد. که خود بسیار در پرفورمنس (به انگلیسی : performance) برنامه تاثیر دارد.
Qt Container :
از آنجایی که Qt یک فریمورک هست. برای اینکه برنامهنویسی به راحتی بتواند با کلاسها و توابع این فریمورک تعامل برقرار کند ؛ Qt یکسری از مخازن (معادل فارسی کانتینر) را بازنویسی کردهاست. که میتوانید در این لینک بیشتر در اینباره مطالعه کنید.
- 1
-
علیکمالسلام ؛
قبل از اینکه به پاسخ مستقیم سؤال بپردازیم ، بیاید درک کنیم چه شد که
template
ها نیاز برنامهنویس شد.این تابع را در نظر بگیر :
int Sum (const int& first, const int& second){ return first+second; }
این تابع دو عدد از نوع
int
دریافت و حاصل جمعشون را بر میگردونه.خب ! حالا چه میشه اگه شما بخواید به جای
int
نوعdouble
ارسال کنید ؟ و برنامهٔ شما با انواع مختلفی داده نیاز داشته باشه که با این تابع کار کنه. شاید بگید خب یک تابع دیگه با پارامتر و نوع بازگشتیdouble
مینویسم.با این روش چه مشکلاتی پیش میآید :
- کد تکراری.
- بالا رفتن درصد خطای کد.
- افزایش بیدلیل حجم کد.
- سخت شدن مدیریت کد.
- مشکل در آپدیت کردن سورس کد.
- و ...
زبان سیپلاسپلاس برای رفع این مشکلما
template
ها را معرفی کرده است.template
ها میتوانند هر نوع دادهای را قبول کنن. تابع زیر ، تابعtemplate
بازنویسی شدهٔ تابعSum
است که در مثال بالا نوشتیم :template <typename newType> newType Sum (const newType& first, const newType& second){ return first + second; }
خییییلی بزرگ شد ن ؟. خب میتونیم کوتاهش کنیم :
template <typename newType> newType Sum (const newType& first, const newType& second){ return first + second; }
- نکته : میدانیم که کامپایلر فاصلههارا نادیده میگیره.
خب ! اوّل برای تبدیل تابع ، به یک تابع
template
باید از کلمهٔ کلیدیtemplate
استفاده کنیم. و بعد با استفاده از< >
اسم نوع دادههای جدیدمان را بنویسیم.-
نکته : ما هیچ نوع دادهٔ جدیدی درواقع تعریف نمیکنیم. این تعریف فقط معرفی یک اسم به عنوان نوع دادهای هست که میتواند به هر چیزی اعم از
int,double ,...
تبدیل بشود.
و داخل
< >
ما از کلمهٔکلیدیtypename
برای تعریف اسم داده استفاده کردیم. و همچنین میتوانیم کلمهٔکلیدیclass
نیز استفاده کنیم که هردو برابر یک دیگر هستن. امّا زمانی شما داریدtemplate
ی ازtemplate
درست میکنید. مثلاً این نمونه :template < template <typename> class MyTmpClass, typename newType>
اینجا دیگه نمیتوانید بین کلمهکلیدی
typename
وclass
تفاوت قائع نشید. چرا که نیازه صراحتاً مشخص. امّا در استاندارد ۱۷ این مشکل وجود ندارد ِ؛ ولی بهتر است که این تفاوت را اعمال کنیم.حال به راحتی میتوانیم تابع را فراخوانی کنیم. به تکه کدزیر توجه کنید
Sum (12 ,32); Sum (1'000'000'000'000,3212'333'233); Sum (std::string("ghasem") , std::string("ramezani")); Sum (12, 32.0);
سه خط اوّل کد بدون مشکل کامپایل میشوند. الا خط آخری. چرا که ما یک پارامتر با نوع
int
و یک پارامتر با نوعdouble
ارسال کردیم.برای حل این مشکل بیاید ببینیم که
template
ها به چه صورت کار میکنند. فرض کنید این تابع را فراخوانی کردیم :Sum ( int , int );
وقتی کامپایلر به این تابع بر میخورد. تابع
template
مارا به اینصورت برای ما بازنویسی میکند :int Sum (const int& first, const int& second){ return first + second; }
خب ! و وقتیما سعی میکنیم این تابع را فراخوانی کنیم :
Sum ( int , double );
برنامه کامپایل نمیشود و خطای زیر را ساطع میکنن. چرا که یک پارامتر
Int
و دیگریdouble
هست../main.cpp:5: candidate template ignored: deduced conflicting types for parameter 'newType' ('int' vs. 'double')
آیا این شکل استفاده از توابع براتون آشنا نیست ؟ یه کم فک کنید :
-
std::vector
-
std::array
-
std::list
تمام این کلاسها ،
template class
هستند. و هر نوعی میتوانند قبول کنند :#include <vector> #include <string> class myClass{ public: myClass(){} }; int main (void){ std::vector <int> myIntger {1,2,3,4}; std::vector <std::string> myString {"ghasem" , "ramezani"}; std::vector <myClass> myClassVector; return 0; }
-
نکته : این توضیح خیلی خلاصه از
template
ها و روش استفاده از آنها بود و به همین دو خط محدود نمیشوند.
نقل قولولی از آنجا که به نظر پیچیده میباشد
و اینکه گفتید "به نظر پیچیده میباشد" . پیچیدگی در عین سادگی یکی از قابلیتهای فوقالعادهٔ زبان سیپلاسپلاسه. اصلاً کد باید وحشتناک باشه.
- 1
- 1
-
با سلام.
در نسخههای قدیمی Qt Creator امکان این وجود داشت ما به راحتی از کلاسهایی مانند
QThread
ارثبری کنیم.نقل قولکه به گفتهٔ یکی از دوستان استفاده از این روش درست نیست. چرا که ما قصد تعمیم کلاس QThread را نداریم.
اما این قابلیت داخل نسخه جدید Qt Creator محدود به چند کلاس خاص اعم از
QObject , QWidget , ...
شده است. آیا روشی برای شخصیسازی این کلاسها میباشد ؟ -
با سلام.
با توجه به اینکه محیط Qt Creator برای استفاده از
QWidget
یاQt Quick
یک محیطبصری هم تعبیه کرده است که کار را برای استفاده راحتتر کرده است. امّا واقعاً استفاده از این ابزار در پروژههای بزرگ درست میباشد ؟ یا اینکه باید از برای کنترل بیشتر با استفاده از کدنویسیمحض طراحیمحیط را به عهده گرفت ؟ در اینصورت ... وظیفهٔ اصلی این محیط طراحی چیست ؟- مثالهایی که خود Qt هم دارد ، بدون استفاده از محیط ویژوال طراحی شده است.
-
مرسی از توضیحاتتون.
بله اطلاع از کراسپلتفرم شدن MS SQL Server دارم... ولی خب مایکروسافت است دیگر ... .
درمورد نیاز واقعی هم گفتم که برنامه حسابداری یه موسسهٔ آموزشی هست که فقط نیاز به ذخیره اطلاعات متنی هست... . این برنامه کلاینت هست و روی دسکتاپ و موبایل قرار خروجی گرفته بشه. که دیتابیس هم داخل سرور هست. و همزمان ممکنه حداکثر ده کاربر به دیتابیس دسترسی داشتهباشن. و با توجه به توضیحات اطلاعات پردازشی سنگین نداریم.
-
با سلام.
معیارها برای انتخاب یک دیتابیس برای یک برنامهٔ حسابداری چه چیزهایی میتواند باشد ؟ بنده درحال شروع نوشتن یک برنامهٔ حسابداری با استفاده از فریمورک Qt هستم. و وهله اوّل که درحال طراحی بخشهای مختلف برنامه هستم نیاز به انتخاب یک دیتابیس دارم. که با وجود تنوع دیتابیسها در این زمینه نیاز دانستم که نظر مابقی دوستان را در این زمینه بدانم.
بنده برنامهی حسابداری هلو را دیدم که از دیتابیس MS SQL Server استفاده میکند. ولی خب برنامهٔ من Cross-Platform میباشد و نمیتوانم از MS SQL Server استفاده کنم.
-
درست متوجه منظورتون نشدم ! ولی :
void Dialog::on_pushButton_2_clicked(){ mThread->Stop = false; }
این اسلات (slot) وقتی صدا زده میشه خب باید مقدار متغیر
MyThread::Stop
رو برابرfalse
قرار بده دیگه ! درسته ؟و طبق دستوراتی که داخل تابع
void MyThread::run
نوشته شده : درصورتیکه این متغیر مقدارشfalse
باشه باید حلقه شکسته بشه و دیگه چیزیemit
نکنه.و وقتی ما این اسلات را فراخوانی میکنیم. اتفاقی نمیافته و باز حلقه به کار خودش ادامه میده.
-
با سلام.
در حال یادگیر
Qt
وThread
ها بودم که به مشکل دسترسی به متغیر در Thread بر خوردم.کلاس زیر از
QThread
مشتق شده است :#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QWidget> #include <QThread> #include <QMutex> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); void run() override; bool Stop; signals: void NumberChanged(int); }; #endif // MYTHREAD_H #include "mythread.h" MyThread::MyThread(QObject *parent) : QThread (parent) { } void MyThread::run() { for(int i=0; i<100000000 ; ++i){ QMutex mutex; mutex.lock(); if (this->Stop) break; mutex.unlock(); emit NumberChanged(i); this->msleep(100); } }
داخل فرم خودم دو
QPushBotton
و یکQLabel
دارم. که یکی از دکمهها (QPushButton
) وظیفه اجرای یکQThread
را دارد و یکی دیگه باعث متوقف کردن کارQThread
ایجاد شده :#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog){ ui->setupUi(this); mThread = new MyThread(this); connect(mThread,SIGNAL(NumberChanged(int)),this,SLOT(onNumberChanged (int))); } Dialog::~Dialog(){ delete ui; } void Dialog::onNumberChanged(int Number){ ui->label->setText(QString::number(Number)); } void Dialog::on_pushButton_clicked(){ mThread->start(); } void Dialog::on_pushButton_2_clicked(){ mThread->Stop = false; }
در کد بالا زمانیکه
on_pushButton_clicked
فراخوانی شد.QThread
را اجرا میکند. و در مقابل زمانیکهon_pushButton_2_clicked
فراخوانی شد. متغیرbool MyThread::Stop
را برابر مقدار false میگذارد که باعث از بین رفتن عملیاتQThread
ایجاد شده میشود. اما در اصل هیچ تفاوتی ایجاد نمیکند ؟ و زمان بستن برنامه با خطای لاگ زیر برخورد میکنم :21:39:20: Starting /tmp/untitled/build-untitled-Desktop_Clang_7_0_0-Debug/untitled... QThread: Destroyed while thread is still running 21:39:32: The program has unexpectedly finished. 21:39:32: The process was ended forcefully. 21:39:32: /tmp/untitled/build-untitled-Desktop_Clang_7_0_0-Debug/untitled crashed.
کجای کار اشتباه شده است ؟
-
با سلام.
به چه روشی میتوان خروجی متن را در لحظه آپدیت کرد.
برای مثال کد زیر را در نظر داشته باشید :
#include <iostream> int main (void){ for(unsigned int index =10 ; index <= 100 ; index+=10) std::cout << index << '%' << std::endl; return 0; }
که خروجی زیر تولید میشه :
[ghasem@clibcore AnotherJustForTest]$ g++ -o main main.cpp && ./main 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
خب ! حالا اگر ما بخواهیم همان خط اول فقط آپدیت بشود و از
10%
تا100%
را در همان خط چاپ کند و دیگر به خط بعدی نرود چه باید کرد ؟یه مثال دیگه ... مدیربستههای
dnf , apt , pacman
که نوارپیشرفتی در خروجی کنسول خود نشان میدن. -
با تشکر از توضیحات شما @فرهاد شیری .
در 1 ساعت قبل، فرهاد شیری گفته است :دقیقا همین اتفاق می افتد منتهی نه در خروجی کامپایل شما بلکه در زمان تبدیل به کد ماشین توسط خود کامپایلر و لینکر این انعقاد انجام می شود
بنده اون لینکی که پیشنهاد داده بودید و بهعلاوه موارد دیگری هم در این زمینه خوانده بودم. و دقیقاً سعی کردم مثالی مرتبط به این موضوع بزنم. پس یه نگاه دیگه به فایل هدری که مثال زده بودم بکنید :
class Base{ public : Base(){std::cout << "BASE#c";} ~Base(){std::cout << "BASE#d";} }; void AnotherTest (void){} void AndAnotherTest(void){}
در فایل
main.cpp
من تنها یک بار تابعAndAnotherTest()
را فراخوانی کرده بودم. که مسلماً طبق چیزی که گفتید :در 1 ساعت قبل، فرهاد شیری گفته است :خروجی باینری شما ترکیبی از کد های کامپایل شده شما خواهد بود به اضافه کلاسها و توابع استاندارد ++C که شما در برنامه خود استفاده کرده اید
و بنده به این صورت برداشت کردم : که ابتدا تمام کد های فایل هدر من کامپایل شده و سپس در زمان لینک ، لینکر میبایست تنها لینکی به تابع
AndAnotherTest()
داشته باشد. و فقط هم این تابع در خروجی کد من باشد.من برای تست این موضوع از تعریف یک کلاس و دو تابع استفاده کردم. از آنجایی که میدونستم کلاس تنها یه نقشه از ساختمان است. پس تا زمانی که از این نقشه نمونهسازی نشوند ، نباید هیچ حافظهای یا کامپایلی برای کد های این کلاس درنظر گرفته بشه. که تا این قسمت با توجه به خروجی اسمبلی من درست بود و حرفی از کلاس
Base
زده نشده بود. اما درمورد دوتا تابع بعدی که دقیقا هر دو کامپایل و درخروجی کد من بودن. در مقایسه هایی که کردم (که تماماً در طوماری که بالا ارسال کردم ، ذکر شده) متوجه شدم تنها تفاوت در فایلی که من تابع را فراخوانی و در فایلی که فراخوانی نکرده بودم تنها یک خط در خروجی اسمبلی بود ؛ اونهم دستور فراخوانی تابعAndAnotherTest()
:[ghasem@clibcore output]$ cat --number JustHeader | egrep "(AnotherTest|AndAnotherTest)" > OnlyHeaderGREP [ghasem@clibcore output]$ cat --number UseOneFunction | egrep "(AnotherTest|AndAnotherTest)" > UseOneFunctionGREP [ghasem@clibcore output]$ diff JustHeader UseOneFunction 55d54 < call _Z14AndAnotherTestv
در مورد هدرفایل
iostream
هم. متغیرها و توابعی که به صورتstatic
یاnon-member function
تعریف شدهاند ، خروجی اسمبلیشان در فایل نهایی من هست. به غیر ازtamplate-function
وtemplate-class
وclass
ها که آنها دقیقا برای کامپایل شدن نیاز به استفاده شدن را دارند.الان دلیل این اتفاق : وجود کد اسمبلی تابع استفاده نشده در فایل هدر ، در خروجی نهایی فایل ترجمه شده به اسمبلی من چیست ؟ و آیا راهی برای جلوگیری از این موضوع هست ؟
-
در ۱ ساعت قبل، سروش ربیعی گفته است :اضافه کردن فایلهای هدر هیچ تأثیری در حجم برنامهٔ نهایی نداره
(عذرخواهی میکنم مطالبی ارسالی این پست به دلیلی خروجی اسمبلی کدها طولانی و خارج از حوصله است. لذا متنهای بین کدها با سبک دُرُشت و اندازه ۱۸ نوشته شده است)
خب مگه اون هدر فایلی که اضافه میکنیم کامپایل نمیشه ؟
الان یک نمونه تستی که من نوشتم :
header.hpp
class Base{ public : Base(){std::cout << "BASE#c";} ~Base(){std::cout << "BASE#d";} }; void AnotherTest (void){} void AndAnotherTest(void){}
main.cpp
#include <iostream> #include "header.hpp" int main(){ return 0; }
خروجی اسمبلی زیر را تولید کرده :
.file "main.cpp" .text .section .rodata .type _ZStL19piecewise_construct, @object .size _ZStL19piecewise_construct, 1 _ZStL19piecewise_construct: .zero 1 .local _ZStL8__ioinit .comm _ZStL8__ioinit,1,1 .text .globl _Z11AnotherTestv .type _Z11AnotherTestv, @function _Z11AnotherTestv: .LFB1524: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1524: .size _Z11AnotherTestv, .-_Z11AnotherTestv .globl _Z14AndAnotherTestv .type _Z14AndAnotherTestv, @function _Z14AndAnotherTestv: .LFB1525: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1525: .size _Z14AndAnotherTestv, .-_Z14AndAnotherTestv .globl main .type main, @function main: .LFB1526: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1526: .size main, .-main .type _Z41__static_initialization_and_destruction_0ii, @function _Z41__static_initialization_and_destruction_0ii: .LFB2010: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl %edi, -4(%rbp) movl %esi, -8(%rbp) cmpl $1, -4(%rbp) jne .L7 cmpl $65535, -8(%rbp) jne .L7 movl $_ZStL8__ioinit, %edi call _ZNSt8ios_base4InitC1Ev movl $__dso_handle, %edx movl $_ZStL8__ioinit, %esi movl $_ZNSt8ios_base4InitD1Ev, %edi call __cxa_atexit .L7: nop leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2010: .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii .type _GLOBAL__sub_I__Z11AnotherTestv, @function _GLOBAL__sub_I__Z11AnotherTestv: .LFB2011: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $65535, %esi movl $1, %edi call _Z41__static_initialization_and_destruction_0ii popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2011: .size _GLOBAL__sub_I__Z11AnotherTestv, .-_GLOBAL__sub_I__Z11AnotherTestv .section .init_array,"aw" .align 8 .quad _GLOBAL__sub_I__Z11AnotherTestv .hidden __dso_handle .ident "GCC: (GNU) 8.2.1 20181105 (Red Hat 8.2.1-5)" .section .note.GNU-stack,"",@progbits
و کد زیر :
#include <iostream> #include "header.hpp" int main(){ AndAnotherTest(); return 0; }
خروجی اسمبلی زیر را تولید کرده :
.file "main.cpp" .text .section .rodata .type _ZStL19piecewise_construct, @object .size _ZStL19piecewise_construct, 1 _ZStL19piecewise_construct: .zero 1 .local _ZStL8__ioinit .comm _ZStL8__ioinit,1,1 .text .globl _Z11AnotherTestv .type _Z11AnotherTestv, @function _Z11AnotherTestv: .LFB1524: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1524: .size _Z11AnotherTestv, .-_Z11AnotherTestv .globl _Z14AndAnotherTestv .type _Z14AndAnotherTestv, @function _Z14AndAnotherTestv: .LFB1525: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1525: .size _Z14AndAnotherTestv, .-_Z14AndAnotherTestv .globl main .type main, @function main: .LFB1526: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 call _Z14AndAnotherTestv movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1526: .size main, .-main .type _Z41__static_initialization_and_destruction_0ii, @function _Z41__static_initialization_and_destruction_0ii: .LFB2010: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl %edi, -4(%rbp) movl %esi, -8(%rbp) cmpl $1, -4(%rbp) jne .L7 cmpl $65535, -8(%rbp) jne .L7 movl $_ZStL8__ioinit, %edi call _ZNSt8ios_base4InitC1Ev movl $__dso_handle, %edx movl $_ZStL8__ioinit, %esi movl $_ZNSt8ios_base4InitD1Ev, %edi call __cxa_atexit .L7: nop leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2010: .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii .type _GLOBAL__sub_I__Z11AnotherTestv, @function _GLOBAL__sub_I__Z11AnotherTestv: .LFB2011: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $65535, %esi movl $1, %edi call _Z41__static_initialization_and_destruction_0ii popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2011: .size _GLOBAL__sub_I__Z11AnotherTestv, .-_GLOBAL__sub_I__Z11AnotherTestv .section .init_array,"aw" .align 8 .quad _GLOBAL__sub_I__Z11AnotherTestv .hidden __dso_handle .ident "GCC: (GNU) 8.2.1 20181105 (Red Hat 8.2.1-5)" .section .note.GNU-stack,"",@progbits
و در کد اسمبلئ که هیچ یک از توابع فایل
header.hpp
استفاده نشده است. خروجی اسمبلی توابع فایلheader.hpp
موجود هست :[ghasem@clibcore tmp]$ cat --number OnlyHeader | egrep "(AnotherTest|AndAnotherTest)" 11 .globl _Z11AnotherTestv 12 .type _Z11AnotherTestv, @function 13 _Z11AnotherTestv: 27 .size _Z11AnotherTestv, .-_Z11AnotherTestv 28 .globl _Z14AndAnotherTestv 29 .type _Z14AndAnotherTestv, @function 30 _Z14AndAnotherTestv: 44 .size _Z14AndAnotherTestv, .-_Z14AndAnotherTestv 92 .type _GLOBAL__sub_I__Z11AnotherTestv, @function 93 _GLOBAL__sub_I__Z11AnotherTestv: 109 .size _GLOBAL__sub_I__Z11AnotherTestv, .-_GLOBAL__sub_I__Z11AnotherTestv 112 .quad _GLOBAL__sub_I__Z11AnotherTestv
و در کدی که فقط تابع
AndAnotherTest()
استفاده شده است :[ghasem@clibcore tmp]$ cat --number UseOneFunction | egrep "(AnotherTest|AndAnotherTest)" 11 .globl _Z11AnotherTestv 12 .type _Z11AnotherTestv, @function 13 _Z11AnotherTestv: 27 .size _Z11AnotherTestv, .-_Z11AnotherTestv 28 .globl _Z14AndAnotherTestv 29 .type _Z14AndAnotherTestv, @function 30 _Z14AndAnotherTestv: 44 .size _Z14AndAnotherTestv, .-_Z14AndAnotherTestv 55 call _Z14AndAnotherTestv 93 .type _GLOBAL__sub_I__Z11AnotherTestv, @function 94 _GLOBAL__sub_I__Z11AnotherTestv: 110 .size _GLOBAL__sub_I__Z11AnotherTestv, .-_GLOBAL__sub_I__Z11AnotherTestv 113 .quad _GLOBAL__sub_I__Z11AnotherTestv
و تنها تفاوت این دو در فراخوانی تابع
AndAnotherTest()
هست :[ghasem@clibcore output]$ cat --number JustHeader | egrep "(AnotherTest|AndAnotherTest)" > OnlyHeaderGREP [ghasem@clibcore output]$ cat --number UseOneFunction | egrep "(AnotherTest|AndAnotherTest)" > UseOneFunctionGREP [ghasem@clibcore output]$ diff JustHeader UseOneFunction 55d54 < call _Z14AndAnotherTestv
در حالی که من از پاسخ شما @سروش ربیعی فهمیدم که گفتید هدرفایلها تاثیری در حجم برنامهٔنهایی نداره. اما مثال بالا که زدم با وجود اینکه هیچ فراخوانی از توابع نشده بود بازم هم کد های هدرفایل کامپایل شد.
و اما بخشی که منو گیج کرده !
ما در این فایل هم هدرفایل
iostream
و همheader.hpp
را وارد برنامه کرده ایم. توابعی که درheader.hpp
بود تماما کامپایل شده و در خروجی اسمبلی هست. اما خبری از توابع و دستوراتiostream
نیست. این خروجی اسمبلی بدون هدرفایلiostream
هست :.file "main.cpp" .text .globl _Z11AnotherTestv .type _Z11AnotherTestv, @function _Z11AnotherTestv: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size _Z11AnotherTestv, .-_Z11AnotherTestv .globl _Z14AndAnotherTestv .type _Z14AndAnotherTestv, @function _Z14AndAnotherTestv: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size _Z14AndAnotherTestv, .-_Z14AndAnotherTestv .globl main .type main, @function main: .LFB2: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE2: .size main, .-main .ident "GCC: (GNU) 8.2.1 20181105 (Red Hat 8.2.1-5)" .section .note.GNU-stack,"",@progbits
و تفاوت آن با خروجی اسمبلیای که هدرفایل
iostream
وجود داشته است :[ghasem@clibcore output]$ diff WithIostream WithoutIostrea 3,10d2 < .section .rodata < .type _ZStL19piecewise_construct, @object < .size _ZStL19piecewise_construct, 1 < _ZStL19piecewise_construct: < .zero 1 < .local _ZStL8__ioinit < .comm _ZStL8__ioinit,1,1 < .text 14c6 < .LFB1518: --- > .LFB0: 26c18 < .LFE1518: --- > .LFE0: 31c23 < .LFB1519: --- > .LFB1: 43c35 < .LFE1519: --- > .LFE1: 48c40 < .LFB1520: --- > .LFB2: 60c52 < .LFE1520: --- > .LFE2: 62,113d53 < .type _Z41__static_initialization_and_destruction_0ii, @function < _Z41__static_initialization_and_destruction_0ii: < .LFB2001: < .cfi_startproc < pushq %rbp < .cfi_def_cfa_offset 16 < .cfi_offset 6, -16 < movq %rsp, %rbp < .cfi_def_cfa_register 6 < subq $16, %rsp < movl %edi, -4(%rbp) < movl %esi, -8(%rbp) < cmpl $1, -4(%rbp) < jne .L7 < cmpl $65535, -8(%rbp) < jne .L7 < movl $_ZStL8__ioinit, %edi < call _ZNSt8ios_base4InitC1Ev < movl $__dso_handle, %edx < movl $_ZStL8__ioinit, %esi < movl $_ZNSt8ios_base4InitD1Ev, %edi < call __cxa_atexit < .L7: < nop < leave < .cfi_def_cfa 7, 8 < ret < .cfi_endproc < .LFE2001: < .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii < .type _GLOBAL__sub_I__Z11AnotherTestv, @function < _GLOBAL__sub_I__Z11AnotherTestv: < .LFB2002: < .cfi_startproc < pushq %rbp < .cfi_def_cfa_offset 16 < .cfi_offset 6, -16 < movq %rsp, %rbp < .cfi_def_cfa_register 6 < movl $65535, %esi < movl $1, %edi < call _Z41__static_initialization_and_destruction_0ii < popq %rbp < .cfi_def_cfa 7, 8 < ret < .cfi_endproc < .LFE2002: < .size _GLOBAL__sub_I__Z11AnotherTestv, .-_GLOBAL__sub_I__Z11AnotherTestv < .section .init_array,"aw" < .align 8 < .quad _GLOBAL__sub_I__Z11AnotherTestv < .hidden __dso_handle
با یه نگاه کردن به فایل
iostream
:#ifndef _GLIBCXX_IOSTREAM #define _GLIBCXX_IOSTREAM 1 #pragma GCC system_header #include <bits/c++config.h> #include <ostream> #include <istream> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION extern istream cin; extern ostream cout; extern ostream cerr; extern ostream clog; #ifdef _GLIBCXX_USE_WCHAR_T extern wistream wcin; extern wostream wcout; extern wostream wcerr; extern wostream wclog; #endif static ios_base::Init __ioinit; _GLIBCXX_END_NAMESPACE_VERSION } #endif
ظاهرا دلیل اون تفاوت هم مشخص هست. اما تکلیف مابقی هدرفایل هایی که داخل
iostream
وارد شده اند چیست ؟ مگه توابع و متغیر های آنها نیز کامپایل نمیشود ؟ پس چرا مثل خروجی کد اسمبلی توابع موجود درheader.hpp
در سورس اسمبلی نهایی نیست ؟ (و باز عذرخواهی میکنم بابت طولانی بودن پست ) -
با سلام.
درحال بررسی کدهای کتابخانههای استاندارد سیپلاسپلاس بودم ، که متوجه موردی شدم ؛ تقریبا بیشتر توابع و کلاسهایی که از کتابخانههای استاندارد استفاده میکنیم دارای مقدار زیادی وابستگی به توابع و فایلهای دیگر دارند. برای مثال تابع
std::swap
که برای جابهجایی دو نوع استفاده میشود به اینصورت میباشد :template<typename _Tp, size_t _Nm> inline typename std::enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(std::__is_nothrow_swappable<_Tp>::value) { for (size_t __n = 0; __n < _Nm; ++__n) swap(__a[__n], __b[__n]); }
که برای کامپایل نیاز به این موارد در دو فایل
move.h
وtype_traits
دارند :template<typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() const noexcept { return value; } #if __cplusplus > 201103L #define __cpp_lib_integral_constant_callable 201304 constexpr value_type operator()() const noexcept { return value; } #endif }; template<bool __v> using __bool_constant = integral_constant<bool, __v>; typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type; template<bool, typename _Tp = void> struct enable_if { }; namespace __swappable_details { using std::swap; struct __do_is_swappable_impl { template<typename _Tp, typename = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))> static true_type __test(int); template<typename> static false_type __test(...); }; struct __do_is_nothrow_swappable_impl { template<typename _Tp> static __bool_constant< noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())) > __test(int); template<typename> static false_type __test(...); }; } template<typename _Tp> struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp> struct __is_swappable : public __is_swappable_impl<_Tp>::type { }; template<typename _Tp> struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp> struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { };
خب ! سوال اول بنده اینجاس که در چنین مواردی ، بهتر نیست که تابع
std::swap
را با توجه به نیازی که داریم خودمان پیادهسازی کنیم ؟ و اینکه آیا این حجم از کد و استفاده ازtemplate
ها هزینه پِرفُورْمَنْس زیادی ندارد ؟و سوال دوم :
تمام این کدها در دو فایل
move.h
وtype_traits
قرار دارد (که مسلماً این فایل ها هم وابستگیهای دیگری به دیگر فایلها دارند). آیا ما نمیتوانیم مثلا فقط تابعstd::swap
را در برنامهٔ خود فراخوانی کنیم که این حجم از کد احتیاج به کامپایل نداشته باشد ؟برای نمونه در زبان برنامهنویسی پایتون ، با استفاده از دستور
import
ما یک ماژول را وارد برنامه میکنیم :import time
در این روش تمام ماژول
time
به فایلما اضافه خواهند شد. درصورتی که ما فقط از ماژولtime
نیاز به تابعsleep
داشته باشیم کافی است که از قابلتfrom ... import ...
استفاده کنیم :from time import sleep
آیا این حرکت در
C++
نیز امکانپذیر هست ؟
اضافه کردن یک کاراکتر به انتهای رشته
در سوالات عامیانه در رابطه با ++C مدرن
ارسال شده در · ویرایش شده در توسط قاسم رمضانی منش
تصحیح حالت رنگآمیزی کدها.
درود بر دوستان عزیز؛
برای اضافه کردن یک کاراکتر به انتهای رشته شاید افراد به اینصورت عمل کنند :
امّا من خواستم بدون وابسته بودن این قسمت به libc؛ این عمل انجام شود به اینصورت عمل کردم :
امّا با سیگنال SIGSEGV در تابع __strlen_sse2() هنگام فراخوانی printf() مواجه میشوم، کلاً حافظهٔ دریافتی از طریق Derefrence کردن string مقادیرش قابل دسترسی نیست (پیغامی که GDB نشان میدهد). ولی همچنان میتوانم بهاینصورت به مقداردهی که کردهام دسترسی داشتهباشم :
الآن چه اتفاقی برای حافظهٔ متغیر string میافتد ؟