Actualized that just one standard library libc++ is being used
36 KiB
machine_translated | machine_translated_rev | toc_priority | toc_title |
---|---|---|---|
true | 72537a2d52 |
68 | چگونه برای نوشتن ج++ کد |
چگونه برای نوشتن ج++ کد
توصیه های عمومی
1. در زیر توصیه, مورد نیاز نیست.
2. اگر شما در حال ویرایش کد, این را حس می کند به دنبال قالب بندی کد های موجود.
3. سبک کد برای سازگاری مورد نیاز است. سازگاری خواندن کد را ساده تر می کند و همچنین باعث می شود که کد را جستجو کنید.
4. بسیاری از قوانین دلایل منطقی ندارند; دیکته شده توسط شیوه های تاسیس شده است.
قالببندی
1. بسیاری از قالب بندی به صورت خودکار انجام می شود clang-format
.
2. فرورفتگی فضاهای 4 هستند. پیکربندی محیط توسعه خود را به طوری که یک تب اضافه می کند چهار فضا.
3. باز و بسته شدن براکت فرفری باید در یک خط جداگانه باشد.
inline void readBoolText(bool & x, ReadBuffer & buf)
{
char tmp = '0';
readChar(tmp, buf);
x = tmp != '0';
}
4. اگر کل بدن تابع یک است statement
, این را می توان در یک خط قرار داده شده. فضاهای محل در اطراف پرانتز فرفری (علاوه بر فضای در پایان خط).
inline size_t mask() const { return buf_size() - 1; }
inline size_t place(HashValue x) const { return x & mask(); }
5. برای توابع. فضاهای اطراف براکت قرار ندهید.
void reinsert(const Value & x)
memcpy(&buf[place_value], &x, sizeof(x));
6. داخل if
, for
, while
و عبارت دیگر, یک فضای در مقابل براکت باز قرار داده(به عنوان مخالف به عملکرد تماس).
for (size_t i = 0; i < rows; i += storage.index_granularity)
7. اضافه کردن فضاهای اطراف اپراتورهای دودویی (+
, -
, *
, /
, %
, …) and the ternary operator ?:
.
UInt16 year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0');
UInt8 month = (s[5] - '0') * 10 + (s[6] - '0');
UInt8 day = (s[8] - '0') * 10 + (s[9] - '0');
8. اگر یک خوراک خط وارد شده است, قرار دادن اپراتور در یک خط جدید و افزایش تورفتگی قبل از.
if (elapsed_ns)
message << " ("
<< rows_read_on_server * 1000000000 / elapsed_ns << " rows/s., "
<< bytes_read_on_server * 1000.0 / elapsed_ns << " MB/s.) ";
9. شما می توانید فضاهای برای هم ترازی در یک خط استفاده, در صورت دلخواه.
dst.ClickLogID = click.LogID;
dst.ClickEventID = click.EventID;
dst.ClickGoodEvent = click.GoodEvent;
10. از فضاهای اطراف اپراتورها استفاده نکنید .
, ->
.
در صورت لزوم اپراتور می تواند به خط بعدی پیچیده شود. در این مورد جبران در مقابل افزایش می یابد.
11. از فضا برای جدا کردن اپراتورهای غیر ضروری استفاده نکنید (--
, ++
, *
, &
, …) from the argument.
12. بعد از ویرگول فاصله بگیر ولی نه قبل از اون همین قاعده برای یک نقطه و ویرگول در داخل یک for
اصطلاح.
13. از فضاها برای جدا کردن استفاده نکنید []
اپراتور
14. در یک template <...>
عبارت, استفاده از یک فضای بین template
و <
; بدون فاصله پس از <
یا قبل از >
.
template <typename TKey, typename TValue>
struct AggregatedStatElement
{}
15. در کلاس ها و سازه, نوشتن public
, private
و protected
در همان سطح به عنوان class/struct
, و تورفتگی بقیه کد.
template <typename T>
class MultiVersion
{
public:
/// Version of object for usage. shared_ptr manage lifetime of version.
using Version = std::shared_ptr<const T>;
...
}
16. اگر همان namespace
برای کل فایل استفاده می شود, و هر چیز دیگری قابل توجهی وجود ندارد, افست در داخل لازم نیست namespace
.
17. اگر بلوک برای if
, for
, while
, یا عبارت دیگر متشکل از یک statement
, براکت فرفری اختیاری هستند. محل statement
در یک خط جداگانه, در عوض. این قانون نیز برای تو در تو معتبر if
, for
, while
, …
اما اگر درونی statement
شامل براکت های فرفری یا else
بلوک خارجی باید در براکت های فرفری نوشته شود.
/// Finish write.
for (auto & stream : streams)
stream.second->finalize();
18. نباید در انتهای خطوط هیچ فضایی وجود داشته باشد.
19. فایل های منبع هستند وزارت مخابرات 8 کد گذاری.
20. شخصیت های غیر ASCII استفاده می شود string literals.
<< ", " << (timer.elapsed() / chunks_stats.hits) << " μsec/hit.";
21. هنوز عبارات متعدد در یک خط ارسال نمی.
22. بخش های گروهی کد در داخل توابع و با بیش از یک خط خالی جدا می شوند.
23. توابع جداگانه, کلاس, و به همین ترتیب با یک یا دو خط خالی.
24. A const
(مربوط به ارزش) باید قبل از نام نوع نوشته شده است.
//correct
const char * pos
const std::string & s
//incorrect
char const * pos
25. هنگام اعلام اشاره گر یا مرجع *
و &
نمادها باید با فاصله در هر دو طرف از هم جدا.
//correct
const char * pos
//incorrect
const char* pos
const char *pos
26. هنگام استفاده از انواع قالب ها با نام مستعار using
کلمه کلیدی (به جز در ساده ترین موارد).
به عبارت دیگر پارامترهای قالب فقط در using
و در کد تکرار نمی شود.
using
می توان به صورت محلی اعلام کرد, مانند داخل یک تابع.
//correct
using FileStreams = std::map<std::string, std::shared_ptr<Stream>>;
FileStreams streams;
//incorrect
std::map<std::string, std::shared_ptr<Stream>> streams;
27. هنوز متغیرهای مختلفی از انواع مختلف در یک بیانیه اعلام نمی.
//incorrect
int x, *y;
28. هنوز کست ج سبک استفاده نمی.
//incorrect
std::cerr << (int)c <<; std::endl;
//correct
std::cerr << static_cast<int>(c) << std::endl;
29. در کلاس ها و ساختار, اعضای گروه و توابع به طور جداگانه در داخل هر دامنه دید.
30. برای کلاس های کوچک و structs آن است که لازم نیست برای جدا کردن روش بیانیه از اجرای.
همان درست است برای روش های کوچک در هر کلاس و یا ساختار است.
برای templated کلاس و structs نیست جداگانه روش اعلامیه از اجرای (زیرا در غیر این صورت آنها باید تعریف شده در ترجمه همان واحد).
31. شما می توانید خطوط در بسته بندی 140 شخصیت, بجای 80.
32. همیشه پیشوند اپراتورهای افزایش/کاهش استفاده کنید اگر پسوند مورد نیاز نمی باشد.
for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it)
توضیحات
1. حتما برای اضافه کردن نظر برای تمام بخش های غیر بدیهی از کد.
این بسیار مهم است. نوشتن نظر ممکن است به شما کمک کند متوجه شوید که کد لازم نیست یا اشتباه طراحی شده است.
/** Part of piece of memory, that can be used.
* For example, if internal_buffer is 1MB, and there was only 10 bytes loaded to buffer from file for reading,
* then working_buffer will have size of only 10 bytes
* (working_buffer.end() will point to position right after those 10 bytes available for read).
*/
2. نظرات می تواند به عنوان دقیق که لازم است.
3. محل نظرات قبل از کد توصیف می کنند. در موارد نادر, نظرات می تواند پس از کد است, در همان خط.
/** Parses and executes the query.
*/
void executeQuery(
ReadBuffer & istr, /// Where to read the query from (and data for INSERT, if applicable)
WriteBuffer & ostr, /// Where to write the result
Context & context, /// DB, tables, data types, engines, functions, aggregate functions...
BlockInputStreamPtr & query_plan, /// Here could be written the description on how query was executed
QueryProcessingStage::Enum stage = QueryProcessingStage::Complete /// Up to which stage process the SELECT query
)
4. نظرات فقط باید به زبان انگلیسی نوشته شود.
5. اگر شما در حال نوشتن یک کتابخانه, شامل نظرات دقیق توضیح در فایل هدر اصلی.
6. هنوز نظر که اطلاعات اضافی را فراهم نمی کند اضافه کنید. به خصوص, نظرات خالی مثل این را ترک کنید:
/*
* Procedure Name:
* Original procedure name:
* Author:
* Date of creation:
* Dates of modification:
* Modification authors:
* Original file name:
* Purpose:
* Intent:
* Designation:
* Classes used:
* Constants:
* Local variables:
* Parameters:
* Date of creation:
* Purpose:
*/
به عنوان مثال با اقتباس از منابع http://home.tamk.fi/~jaalto/دوره آموزشی/برنامه نویسی به سبک/doc/قابل نگهداشت-کد/.
7. هنوز نظرات زباله ارسال کنید (نویسنده, تاریخ ایجاد ..) در ابتدای هر فایل.
8. نظرات تک خط با سه اسلش شروع می شود: ///
و نظرات چند خط با شروع /**
. این نظرات در نظر گرفته شده است “documentation”.
توجه: شما می توانید داکسیژن برای تولید اسناد از این نظرات استفاده کنید. اما داکسیگن به طور کلی استفاده نمی شود زیرا راحت تر است که کد را در محیط برنامه نویسی حرکت دهید.
9. نظرات چند خط باید خطوط خالی در ابتدا و پایان ندارد (به جز خط که بسته یک نظر چند خط).
10. برای اظهار نظر از کد, استفاده از نظرات اساسی, نه “documenting” نظر.
11. حذف بخش هایی از کد اظهار نظر قبل از ارتکاب.
12. هنوز ناسزا در نظرات و یا کد استفاده کنید.
13. از حروف بزرگ استفاده نکنید. هنوز نقطه گذاری بیش از حد استفاده کنید.
/// WHAT THE FAIL???
14. هنوز نظر را به محیطی استفاده نمی.
///******************************************************
15. هنوز بحث در نظرات شروع نشد.
/// Why did you do this stuff?
16. بدون نیاز به نوشتن نظر در پایان یک بلوک توصیف چه بود وجود دارد.
/// for
نامها
1. استفاده از حروف کوچک با رکورد در نام متغیرها و اعضای کلاس.
size_t max_block_size;
2. نام توابع (روش) استفاده از camelCase آغاز با حروف کوچک نامه.
std::string getName() const override { return "Memory"; }
3. برای نام کلاس ها (structs) استفاده از CamelCase آغاز با حروف بزرگ نامه. پیشوند دیگر از من برای رابط استفاده نمی شود.
class StorageMemory : public IStorage
4. using
به همان شیوه به عنوان کلاس به نام, و یا با _t
در پایان.
5. نام استدلال نوع الگو: در موارد ساده, استفاده T
; T
, U
; T1
, T2
.
برای موارد پیچیده تر, هم پیروی از قوانین برای نام کلاس, و یا اضافه کردن پیشوند T
.
template <typename TKey, typename TValue>
struct AggregatedStatElement
6. نام استدلال ثابت الگو: هم پیروی از قوانین برای نام متغیر, و یا استفاده N
در موارد ساده.
template <bool without_www>
struct ExtractDomain
7. برای کلاس های انتزاعی (رابط) شما می توانید اضافه کنید I
پیشوند.
class IBlockInputStream
8. اگر شما استفاده از یک متغیر به صورت محلی, شما می توانید نام کوتاه استفاده.
در تمام موارد دیگر, استفاده از یک نام است که معنای توصیف.
bool info_successfully_loaded = false;
9. اسامی define
بازدید کنندگان و ثابت جهانی استفاده از همه_کاپ با زیرخط.
#define MAX_SRC_TABLE_NAMES_TO_STORE 1000
10. نام فایل باید همان سبک به عنوان مطالب خود استفاده کنید.
اگر یک فایل شامل یک کلاس, نام فایل به همان شیوه به عنوان کلاس (بالش).
اگر فایل شامل یک تابع واحد, نام فایل به همان شیوه به عنوان تابع (بالش).
11. اگر نام شامل مخفف, سپس:
- برای نام متغیر مخفف حروف کوچک استفاده کنید
mysql_connection
) نهmySQL_connection
). - برای نام کلاس ها و توابع, نگه داشتن حروف بزرگ در مخفف
MySQLConnection
) نهMySqlConnection
).
12. استدلال سازنده استفاده می شود که فقط به مقداردهی اولیه اعضای کلاس باید به همان شیوه به عنوان اعضای کلاس به نام, اما با تاکید در پایان.
FileQueueProcessor(
const std::string & path_,
const std::string & prefix_,
std::shared_ptr<FileHandler> handler_)
: path(path_),
prefix(prefix_),
handler(handler_),
log(&Logger::get("FileQueueProcessor"))
{
}
پسوند تاکید می توان حذف اگر استدلال در بدن سازنده استفاده نمی شود.
13. هیچ تفاوتی در نام متغیرهای محلی و اعضای کلاس وجود دارد (هیچ پیشوندهای مورد نیاز).
timer (not m_timer)
14. برای ثابت در یک enum
استفاده از CamelCase با حرف بزرگ. ت_کاپها نیز قابل قبول است. اگر enum
غیر محلی است, استفاده از یک enum class
.
enum class CompressionMethod
{
QuickLZ = 0,
LZ4 = 1,
};
15. همه نامها باید به زبان انگلیسی باشد. ترجمه کلمات روسی مجاز نیست.
not Stroka
16. اختصارات قابل قبول هستند در صورتی که به خوبی شناخته شده است (زمانی که شما به راحتی می توانید معنای مخفف در ویکیپدیا و یا در یک موتور جستجو پیدا کنید).
`AST`, `SQL`.
Not `NVDH` (some random letters)
کلمات ناقص قابل قبول است اگر نسخه کوتاه استفاده مشترک است.
شما همچنین می توانید مخفف استفاده کنید اگر نام کامل در کنار در نظرات گنجانده شده است.
17. نام فایل با ج++ کد منبع باید .cpp
گسترش. فایل های هدر باید داشته باشند .h
گسترش.
نحوه نوشتن کد
1. مدیریت حافظه.
تخصیص حافظه دستی (delete
) تنها می تواند در کد کتابخانه استفاده می شود.
در کد کتابخانه delete
اپراتور تنها می تواند در مخرب استفاده می شود.
در کد برنامه, حافظه باید توسط شی که صاحب رهایی.
مثالها:
- ساده ترین راه این است که یک شی را روی پشته قرار دهید یا عضو یک کلاس دیگر شوید.
- برای تعداد زیادی از اشیای کوچک از ظروف استفاده کنید.
- برای تخصیص خودکار تعداد کمی از اشیا که در پشته قرار دارند استفاده کنید
shared_ptr/unique_ptr
.
2. مدیریت منابع.
استفاده RAII
و بالا را ببینید.
3. رفع خطا.
استفاده از استثنا. در بیشتر موارد, شما فقط نیاز به پرتاب یک استثنا, و لازم نیست برای گرفتن (به دلیل RAII
).
در برنامه های پردازش داده ها نیست, اغلب قابل قبول برای گرفتن استثنا نیست.
در سرور هایی که رسیدگی به درخواست کاربر, این معمولا به اندازه کافی برای گرفتن استثنا در سطح بالای کنترل اتصال.
در توابع موضوع, شما باید گرفتن و نگه داشتن همه استثنا به تجدید نظر در موضوع اصلی پس از join
.
/// If there weren't any calculations yet, calculate the first block synchronously
if (!started)
{
calculate();
started = true;
}
else /// If calculations are already in progress, wait for the result
pool.wait();
if (exception)
exception->rethrow();
هرگز استثنا بدون دست زدن به پنهان. هرگز فقط کورکورانه قرار دادن همه استثنا برای ورود به سیستم.
//Not correct
catch (...) {}
اگر شما نیاز به چشم پوشی از چند استثنا, انجام این کار تنها برای افراد خاص و تجدید نظر بقیه.
catch (const DB::Exception & e)
{
if (e.code() == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION)
return nullptr;
else
throw;
}
هنگام استفاده از توابع با کدهای پاسخ یا errno
, همیشه نتیجه را بررسی کنید و پرتاب یک استثنا در صورت خطا.
if (0 != close(fd))
throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE);
Do not use assert
.
4. انواع استثنا.
بدون نیاز به استفاده از سلسله مراتب استثنا پیچیده در کد نرم افزار وجود دارد. متن استثنا باید قابل فهم برای یک مدیر سیستم.
5. پرتاب استثنا از destructors.
این توصیه نمی شود, اما مجاز است.
از گزینه های زیر استفاده کنید:
- ایجاد یک تابع (
done()
یاfinalize()
) که همه کار در پیش است که ممکن است منجر به یک استثنا انجام دهد. در صورتی که تابع نامیده می شد, باید بدون استثنا در مخرب بعد وجود داشته باشد. - کارهایی که بیش از حد پیچیده هستند (مانند ارسال پیام بر روی شبکه) را می توان در روش جداگانه قرار داده است که کاربر کلاس باید قبل از تخریب تماس بگیرید.
- اگر یک استثنا در مخرب وجود دارد, بهتر است به سیستم وارد شوید از برای مخفی کردن (اگر چوب در دسترس است).
- در برنامه های ساده, قابل قبول است به تکیه بر
std::terminate
(برای مواردnoexcept
به طور پیش فرض در ج++11) برای رسیدگی به استثنا.
6. بلوک کد ناشناس.
شما می توانید یک بلوک کد جداگانه در داخل یک تابع واحد به منظور ایجاد متغیرهای خاص محلی ایجاد, به طوری که مخرب نامیده می شوند در هنگام خروج از بلوک.
Block block = data.in->read();
{
std::lock_guard<std::mutex> lock(mutex);
data.ready = true;
data.block = block;
}
ready_any.set();
7. چند رشته.
در برنامههای پردازش داده برونخط:
- سعی کنید بهترین عملکرد ممکن را در یک هسته پردازنده تک دریافت کنید. سپس می توانید کد خود را در صورت لزوم موازی کنید.
در برنامه های سرور:
- استفاده از استخر موضوع برای پردازش درخواست. در این مرحله, ما هیچ وظایفی که مورد نیاز تعویض زمینه فضای کاربری نداشته اند.
چنگال برای موازی سازی استفاده نمی شود.
8. همگام سازی موضوعات.
اغلب ممکن است موضوعات مختلف از سلول های حافظه مختلف (حتی بهتر: خطوط کش مختلف) استفاده کنند و از هماهنگ سازی موضوع (به جز joinAll
).
اگر هماهنگ سازی مورد نیاز است, در بیشتر موارد, کافی است به استفاده از امکانپذیر تحت lock_guard
.
در موارد دیگر استفاده از شکلهای هندسی اولیه هماهنگ سازی سیستم. هنوز انتظار مشغول استفاده کنید.
عملیات اتمی باید تنها در ساده ترین موارد استفاده می شود.
سعی نکنید ساختارهای داده ای بدون قفل را اجرا کنید مگر اینکه منطقه اصلی تخصص شما باشد.
9. اشاره گر در مقابل مراجع.
در بیشتر موارد, ترجیح می دهند مراجع.
10. توایع.
استفاده از منابع ثابت اشاره گر به ثابت, const_iterator
, و روش توایع.
در نظر بگیرید const
به طور پیش فرض و استفاده غیر-const
فقط در صورت لزوم.
هنگام عبور متغیرها بر اساس ارزش, با استفاده از const
معمولا معنی ندارد.
11. امضا نشده.
استفاده unsigned
در صورت لزوم
12. انواع عددی.
استفاده از انواع UInt8
, UInt16
, UInt32
, UInt64
, Int8
, Int16
, Int32
و Int64
, و همچنین size_t
, ssize_t
و ptrdiff_t
.
از این نوع برای اعداد استفاده نکنید: signed/unsigned long
, long long
, short
, signed/unsigned char
, char
.
13. عبور استدلال.
رمز عبور مقادیر پیچیده توسط مرجع (محتوی std::string
).
اگر یک تابع قطاری مالکیت یک شی ایجاد شده در پشته, را از نوع استدلال shared_ptr
یا unique_ptr
.
14. ارزش بازگشت.
در اکثر موارد فقط استفاده کنید return
. ننویس [return std::move(res)]{.strike}
.
اگر تابع یک شی در پشته اختصاص و بازده, استفاده shared_ptr
یا unique_ptr
.
در موارد نادر شما ممکن است نیاز به بازگشت به ارزش از طریق بحث و جدل. در این مورد استدلال باید مرجع باشد.
using AggregateFunctionPtr = std::shared_ptr<IAggregateFunction>;
/** Allows creating an aggregate function by its name.
*/
class AggregateFunctionFactory
{
public:
AggregateFunctionFactory();
AggregateFunctionPtr get(const String & name, const DataTypes & argument_types) const;
15. فضای نام.
بدون نیاز به استفاده از یک جداگانه وجود دارد namespace
برای کد برنامه.
کتابخانه های کوچک هم به این نیاز ندارند.
برای کتابخانه های متوسط تا بزرگ, همه چیز را در یک namespace
.
در کتابخانه .h
پرونده, شما می توانید استفاده کنید namespace detail
برای مخفی کردن اطلاعات پیاده سازی برای کد برنامه مورد نیاز نیست.
در یک .cpp
پرونده, شما می توانید یک استفاده static
یا فضای نام ناشناس برای مخفی کردن نمادها.
همچنین یک namespace
می تواند برای یک استفاده شود enum
برای جلوگیری از نام های مربوطه را از افتادن به یک خارجی namespace
(اما بهتر است از یک enum class
).
16. مقدار دهی اولیه معوق.
اگر استدلال برای مقدار دهی اولیه مورد نیاز, سپس شما به طور معمول باید یک سازنده به طور پیش فرض ارسال کنید.
اگر بعد شما نیاز به تاخیر دهی اولیه, شما می توانید یک سازنده به طور پیش فرض است که یک شی نامعتبر ایجاد اضافه. یا برای تعداد کمی از اشیا می توانید استفاده کنید shared_ptr/unique_ptr
.
Loader(DB::Connection * connection_, const std::string & query, size_t max_block_size_);
/// For deferred initialization
Loader() {}
17. توابع مجازی.
اگر کلاس برای استفاده چند شکل در نظر گرفته شده, شما لازم نیست که به توابع مجازی. این نیز به مخرب اعمال می شود.
18. کدگذاریها.
استفاده از اوتیف - 8 در همه جا. استفاده std::string
وchar *
. استفاده نشود std::wstring
وwchar_t
.
19. ثبت.
نمونه در همه جا در کد را ببینید.
قبل از ارتکاب, حذف همه بی معنی و اشکال زدایی ورود به سیستم, و هر نوع دیگری از خروجی اشکال زدایی.
ورود به چرخه باید حتی در سطح ردیابی اجتناب شود.
سیاهههای مربوط باید در هر سطح ورود به سیستم قابل خواندن باشد.
ورود به سیستم تنها باید در کد نرم افزار مورد استفاده قرار, در بیشتر قسمت ها.
ورود پیام باید به زبان انگلیسی نوشته شده است.
ورود ترجیحا باید برای مدیر سیستم قابل فهم باشد.
هنوز ناسزا در ورود به سیستم استفاده کنید.
استفاده از جی تی اف 8 را پشتیبانی می کند در ورود به سیستم. در موارد نادر شما می توانید شخصیت های غیر اسکی در ورود به سیستم استفاده کنید.
20. ورودی-خروجی.
استفاده نکنید iostreams
در چرخه های داخلی که برای عملکرد برنامه حیاتی هستند (و هرگز استفاده نکنید stringstream
).
استفاده از DB/IO
کتابخانه به جای.
21. تاریخ و زمان.
دیدن DateLUT
کتابخونه.
22. شامل شدن.
همیشه استفاده کنید #pragma once
به جای شامل نگهبانان.
23. با استفاده از.
using namespace
استفاده نمی شود. شما می توانید استفاده کنید using
با چیزی خاص. اما محلی در داخل یک کلاس و یا تابع را.
24. استفاده نشود trailing return type
برای توابع مگر اینکه لازم باشد.
[auto f() -> void;]{.strike}
25. اعلامیه و مقدار دهی اولیه از متغیرهای.
//right way
std::string s = "Hello";
std::string s{"Hello"};
//wrong way
auto s = std::string{"Hello"};
26. برای توابع مجازی, نوشتن virtual
در کلاس پایه, اما ارسال override
به جای virtual
در کلاس های نسل نو.
ویژگی های استفاده نشده از سی++
1. ارث مجازی استفاده نمی شود.
2. ویژگی استثنا از ج++03 استفاده نمی شود.
سکو
1. ما نوشتن کد برای یک پلت فرم خاص.
اما چیزهای دیگر برابر بودن, کراس پلت فرم و یا کد قابل حمل ترجیح داده می شود.
2. زبان: ج++20.
3. کامپایلر: gcc
. در این زمان (اوت 2020), کد با استفاده از نسخه وارد شده 9.3. (همچنین می تواند با استفاده از وارد شود clang 8
.)
کتابخانه استاندارد استفاده شده است (libc++
).
**4.**سیستم عامل: لینوکس اوبونتو, مسن تر از دقیق نیست.
**5.**کد برای معماری پردازنده ایکس86_64 نوشته شده است.
مجموعه دستورالعمل پردازنده حداقل مجموعه پشتیبانی در میان سرورهای ما است. در حال حاضر, این سوس است 4.2.
6. استفاده -Wall -Wextra -Werror
پرچم تلفیقی.
7. استفاده از لینک کردن استاتیک با تمام کتابخانه ها به جز کسانی که به سختی برای اتصال به استاتیک (خروجی را ببینید ldd
فرمان).
8. کد توسعه یافته است و با تنظیمات انتشار دیباگ.
ابزارها
1. KDevelop خوب است IDE.
2. برای اشکالزدایی, استفاده gdb
, valgrind
(memcheck
), strace
, -fsanitize=...
یا tcmalloc_minimal_debug
.
3. برای پروفایل استفاده کنید Linux Perf
, valgrind
(callgrind
), یا strace -cf
.
4. منابع در دستگاه گوارش هستند.
5. استفاده مجمع CMake
.
6. برنامه ها با استفاده از منتشر deb
بسته.
7. مرتکب به استاد باید ساخت شکستن نیست.
هر چند تجدید نظر تنها انتخاب شده قابل اجرا در نظر گرفته.
8. مرتکب به عنوان اغلب به عنوان امکان پذیر است, حتی اگر کد تنها تا حدی اماده.
استفاده از شاخه برای این منظور.
اگر کد شما در master
شاخه هنوز قابل ساختن نیست و از قبل از ساخت حذف می شود push
. باید تمومش کنی یا ظرف چند روز حذفش کنی
9. برای تغییرات غیر بدیهی از شاخه ها استفاده کنید و بر روی سرور منتشر کنید.
10. کد استفاده نشده است از مخزن حذف شده است.
کتابخانهها
1. ج++20 کتابخانه استاندارد استفاده شده است (پسوند تجربی مجاز), و همچنین boost
و Poco
چارچوب.
2. در صورت لزوم, شما می توانید هر کتابخانه شناخته شده موجود در بسته سیستم عامل استفاده.
اگر یک راه حل خوب در حال حاضر در دسترس وجود دارد, سپس استفاده کنید, حتی اگر به این معنی شما باید برای نصب کتابخانه دیگر.
(اما برای حذف کتابخانه های بد از کد تهیه می شود.)
3. شما می توانید یک کتابخانه است که در بسته نیست نصب, اگر بسته لازم نیست که چه شما نیاز دارید و یا یک نسخه منسوخ شده و یا نوع اشتباه از تلفیقی.
4. اگر کتابخانه کوچک است و سیستم ساخت پیچیده خود را ندارد, قرار دادن فایل های منبع در contrib
پوشه
5. اولویت همیشه به کتابخانه هایی که در حال حاضر در حال استفاده هستند داده می شود.
توصیه های عمومی
1. ارسال کد به عنوان کوچک که ممکن است.
2. ساده ترین راه حل را امتحان کنید.
3. کد را بنویسید تا بدانید چگونه کار می کند و چگونه حلقه داخلی عمل می کند.
4. در ساده ترین موارد استفاده کنید using
به جای کلاس و یا ساختار.
5. در صورت امکان, انجام سازنده کپی ارسال کنید, اپراتورهای انتساب, مخرب (به غیر از یک مجازی, اگر کلاس شامل حداقل یک تابع مجازی), حرکت سازنده و یا اپراتورهای انتساب حرکت. به عبارت دیگر, توابع کامپایلر تولید باید به درستی کار. شما می توانید استفاده کنید default
.
6. ساده سازی کد تشویق می شود. کاهش اندازه کد خود را در صورت امکان.
توصیه های اضافی
1. به صراحت مشخص std::
برای انواع از stddef.h
توصیه نمی شود. به عبارت دیگر توصیه می کنیم نوشتن کنید size_t
در عوض std::size_t
چون کوتاهتر است .
این قابل قبول است برای اضافه کردن std::
.
2. به صراحت مشخص std::
برای توابع از کتابخانه استاندارد ج
توصیه نمی شود. به عبارت دیگر, نوشتن memcpy
به جای std::memcpy
.
دلیل این است که توابع غیر استاندارد مشابه وجود دارد, مانند memmem
. ما با استفاده از این توابع در مناسبت. این توابع در وجود ندارد namespace std
.
اگر شما ارسال std::memcpy
به جای memcpy
پس همه جا memmem
بدون std::
نگاه عجیب و غریب.
با این اوصاف, شما هنوز هم می توانید استفاده کنید std::
اگر شما ترجیح می دهند.
3. با استفاده از توابع از ج زمانی که همان در استاندارد ج++ کتابخانه در دسترس هستند.
این قابل قبول است اگر کارایی بیشتری داشته باشد.
برای مثال استفاده کنید memcpy
به جای std::copy
برای کپی کردن تکه های زیادی از حافظه است.
4. استدلال تابع چند خطی.
هر یک از سبک های بسته بندی زیر مجاز است:
function(
T1 x1,
T2 x2)
function(
size_t left, size_t right,
const & RangesInDataParts ranges,
size_t limit)
function(size_t left, size_t right,
const & RangesInDataParts ranges,
size_t limit)
function(size_t left, size_t right,
const & RangesInDataParts ranges,
size_t limit)
function(
size_t left,
size_t right,
const & RangesInDataParts ranges,
size_t limit)