Re: Як створити екземпляр класу і як додати в нього конструктора?
В яку ще дипресію?
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Як створити екземпляр класу і як додати в нього конструктора?
Сторінки Попередня 1 … 5 6 7 8 Наступна
Для відправлення відповіді ви повинні увійти або зареєструватися
В яку ще дипресію?
В таку, що навіть не подивився, як я слово "депресія" написав...
Поки що я встановив, що якщо функція знає, який об'єкт вона поверне, то він конструюється безпосередньо там, куди і має повернутися, і ніякі додаткові конструктори не викликаються. Тобто
MyString tmp=..., tmp1=...;
return rand()%2?tmp:tmp1;
викликає 3 конструктори (2 з параметром і 1 копіювання, коли зберігається результат), як і має бути; а от
MyString tmp=...;
return tmp;
викликає тільки 1 конструктор з параметром, причому і в VS, і в GCC! Схоже на неявний inline із оптимізацією. В стандарті я такого поки не знайшов. Куритиму далі...
от що надибав
This is your problem:
return i ? tmp1 : tmp2;
A local variable in a function will only be moved from in the return statement if the return statement is just return var;. If you want to do that test you will need to use an if:
if (i) {
return tmp1;
} else {
return tmp2;
}
спробуйте if
от ще якесь лайно по темі
http://en.wikipedia.org/wiki/Copy_elision
Так, це пункт 12.8.31 стандарту. Дякую.
Отак, вік живи... Тепер піду депресувати з приводу вашого безпосереднього питання...
Так, це пункт 12.8.31 стандарту. Дякую.
Отак, вік живи... Тепер піду депресувати з приводу вашого безпосереднього питання...
12.8.15, мабуть.
http://www.open-std.org/jtc1/sc22/wg21/ … /n3376.pdf
12.8.31.
У вас є остаточний стандарт? Поділитеся? Втім, гадаю, там те саме - в чернетці C++14 це теж 12.8.31.
Та ні, Гугель підсунув мені драфт 2005 року, там це 15-й пункт. А я наївно думав, що в нумерації параграфів зберігається зворотня сумісність.
Ми тут за C++11 говоримо. В C++14 сумісність, гадаю, переважно збережено, а от в C++17 можуть бути і зміни.
Пане koala, ви писали чи то про конструктор переміщення, чи то про оператор присвоєння переміщення (ОПП) наступне
І якщо ми робимо
MyString(MyString&& copy) { str = copy.str; }
А copy здихає, то це ж значить, що в нього викличеться деструктор, котрий звільний пам'ять, на котру тепер вказує str?
Вітаю, ви пройшли перший рівень Так, такий оператор дійсно некоректний. Коректно буде зробити
std::swap( str, copy.str );
і хай деструктор copy звільняє старий str.
Не знаю, як з конструктором, але з оператором переміщення це не працює. Зараз поясню, чому.
Коли ми пишемо
MyString mys = "abcdabe";
MyString mys1 = " rrra";
MyString mys2;
mys2 = mys + mys1;
то під час виклику ОПП, котрий стосується класу mys2, змінна mys2::str ні на що не вказує, в мене вона вказувала на 0x000000. І коли ми робимо swap, то змінюємо значення, на котрі вказує змінна mys2::str, і тимчасового класу, котрий створюється під час mys+mys1, після роботи ОПП тимчасовий об'єкт знищується, тобто викликається його деструктор, котрий намагається звільнити пам'ять на котру вказує вказівник str, але ж після swap він почав вказувати на 0x000000, і тут вже виникає помилка.
Ну ви зрозуміли, ага?
Ви мене рятуєте з депресії Це одна з виразних відмінностей C++98 і C++11 - п. 3.7.4.2.3:
...The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect...
ну, я радий, а ще я радий, що не знаю c++98, бо тоді мені було б ще важче, ліл
Щось я не можу наздогнати, що має робити operator=.
Ну я подумав, по суті лівий операнд має вказувати на ті ж дані, що й правий, ага? Та й написав ось так
void operator=(MyString& other)
{
std::cout << "operator = " << std::endl;
delete[] str;
str=other.str;
}
Але ж ми розуміємо, що при виходу відповідних змінних з активної області бачення у цих змінних викличеться деструктор, перший спрацює нормально, а от другий спробує звільнити вже звільнену пам'ять.
{
MyString mys = "abcdabe";
MyString mys1 = " rrra";
mys = mys1;
std::cout << mys << std::endl;
}
То що ж має робити той operator= ?
Копіювати, звісно. Не
str=other.str;
а
strcpy(str, other.str);
Копіювати, звісно. Не
str=other.str;
а
strcpy(str, other.str);
то це типу як оператор присвоєння копії? ліл
ей, я думав, що cstring - це те ж саме, що й string. Але в cstring немає getline()
<cstring> - це бібліотека мови C (там вона зветься string.h) для роботи з char* - рядками (знову ж таки, не гугліть зображення про ЦЕ).
<cstring> - це бібліотека мови C (там вона зветься string.h) для роботи з char* - рядками (знову ж таки, не гугліть зображення про ЦЕ).
а я думав, що то в C просто string.h, а в C++ якийсь новий стандарт, що типу бібліотеки записуються починаючи з букви "c"
Ви абсолютно правильно подумали.
Ви абсолютно правильно подумали.
тоді чо оті дві біблиотеки різні?