חזור לתיקייה: 02340124 - מבוא לתכנות מערכות

7 - פרקים אחרונים

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה
  • Automatic Type Inference
  • Move Semantics

7 - פרקים אחרונים

02340124

מבוא לתכנות מערכות

רשימות הרצאה לקריאה בשבת

פרקים אחרונים

הופק מתוך תקיית התואר של שקד

uni-folder.vercel.app

Automatic Type Inference

נניח ואנו משתמשים במחלקות של stlstlstl יווצרו לנו שורות אורוכות ומסובכות:

std::vector<int>::iterator iter = std::find(ids.begin(), ids.end(), 315085121);
std::pair<std::string, std::string> firstAndLastNames = std::minmax(
	names.begin(), names.end()
);
std::chrono::time_point<std::chrono::system_clock> time = std::chrono::system_clock::now();

לשם כך, נוכל להשתמש ב-autoautoauto ובכך ניתן ל-C++C++C++ להבין לבד מה הטיפוס.

הערה

זה לא טיפוס שיכול להחליף טיפוסים כמו פייטון, אלא פשוט המהדר יגיד לנו מהו הטיפוס ועדיין יפעלו עליו כל החוקים.

auto iter = std::find(ids.begin(), ids.end(), 315085121);
auto firstAndLastNames = std::minmax(names.begin(), names.end());
auto time = std::chrono::system_clock::now();
הערה

אם נרצה שהטיפוס יהיה רפרנס, אזי נדרש לכתוב auto&auto\&auto& וכך גם ל-const  auto&const\;auto\&constauto&.

vector<string> names;
vector<int> ids;
auto& namesRef = names;
const auto& idsRef = ids;

חשוב להשתמש ב-autoautoauto אך ורק כשסוג המשתנה ברור לגמרי ושאין שום תהיה לגביו.

הערה (מקרים שחייבים להשתמש ב-autoautoauto עבורם)

אם נניח אנו לא יודעים את סוג הטיפוס המוחזר מ-templatetemplatetemplate מסויים לדוגמה:

template <class Sequance>
void printMax(const Sequence& seq, int n)
{
	auto maxval = seq[0];
	for (int i = 0; i < n; ++i)
	{
		maxval = seq[i] > maxval ? seq[i] : maxval;
	}
	cout << maxval;
}

אם נניח אנו לא יודעים את טיפוס ההחזרה כמו פה:

template <class T, class U>
auto multiply(T x, U y)
{
	auto res = x * y;
	return res;
}

Move Semantics

כאשר דיברנו על בנאי העתקה ואופרטור השמה, אמרנו כי אנו לא מעוניינים לבצע אותם לרוב.
לרוב ההעתקה מיותרת ופוגעת בביצועים.

הגדרה 1 (lvalueslvalueslvalues and rvaluesrvaluesrvalues)

lvalue is a value that can be assigned to.
rvalue is a value that can't be assigned to.

דוגמה (rvaluesrvaluesrvalues)

קבועים: 10,"C++"10,\text{"C++"}10,"C++".
return values of functions and operators: height * width or Set<int>::union(x, y)

דוגמה (lvalueslvalueslvalues)

משתנים גלובאליים: std::coutstd::coutstd::cout.
משתנים לוקאליים: int i; Set<int> x;.
פרמטרים לפונקציות f(x);

בתכלס, מה שאנחנו רוצים פה זה ליצור בנאים ופונקציות אשר לא ידרשו העתקות מיותרות.
נגדיר move  operatormove\;operatormoveoperator כך:

template <class T>
class Set
{
	int size;
	int maxSize;
	T* data;
public:
	Set(const Set&); // copy c'tor
	Set(Set&&);      // move c'tor
	
	Set& operator=(const Set&); // copy assignment operator
	Set& operator=(Set&&);      // move assignment operator
};

template<class T>
Set<T>::Set(Set&& other) : size(other.size), maxSize(other.maxSize), data(other.data)
{
	// other no longer controls original memory
	other.size = other.maxSize = 0;
	other.data = nullptr;
}
הערה

כדי להכריח הזזה נוכל להשתמש ב-std::movestd::movestd::move.