作者poyenc (髮箍)
看板C_and_CPP
標題Re: [問題] C++初始化為何常使用單冒號?
時間Wed Nov 25 05:11:00 2020
※ 引述《d630200x (DOGE)》之銘言:
: 有看到有人說這樣效率比較好
: 但我自己測試來看是看不出差異(可能是我測試方式太簡單)
: 就我個人來說我是覺得寫在函式裡較為美觀
: 但是很多網路上的無論是simple code還是教學,在初始化時是比較常看到單冒號的
: 請問是真的效率上差很多,還是單純風格差異而已?
: -----
: Sent from JPTT on my Asus ASUS_I01WD.
這在
語法還有
語意上有不同的考量, 後面會舉兩個例子說明.
語法
通常初學者會有這個問題是因為使用到
SemiRegular 型別物件作為資料成員
, 如
int,
double 等等 vocabulary type, 它們都有功能相仿的建構子
(constructor) 及
operator=() 可呼叫. 不妨寫個類別實驗看看兩種寫法有
什麼差異:
#include <cstdio>
struct MyInt {
MyInt() { puts(
__PRETTY_FUNCTION__); }
MyInt(
int) { puts(
__PRETTY_FUNCTION__); }
MyInt&
operator=(
int) {
puts(
__PRETTY_FUNCTION__);
return *
this;
}
};
struct Test {
Test() { i =
0; }
Test(
bool) : i(
0) {}
MyInt i;
};
Test();
// print: MyInt::MyInt()
// MyInt& MyInt::operator=(int)
Test(
true);
// print: MyInt::MyInt(int)
建構子是絕對會被呼叫的函式, 因此物件的狀態若能在建構子裡面準備好, 就
不需要額外呼叫別的函式做重複的事情.
語意
資料成員/父類別也算是物件的一部分, 在它們的建構子都成功結束的前提下
, 我們才有辦法建構出完整的物件. 所以語言設計上你無法消除從資料成員/
父類別建構子丟出的例外:
#include <iostream>
#include <stdexcept>
struct Foo {
Foo() {
throw std::runtime_error(
"message"); }
};
struct Bar {
Bar()
try {
// constructor body
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
// exception will be re-thrown here
}
Foo foo;
};
對 std::vector 這類會在獲取記憶體失敗時丟出例外的資料成員, 我們可以
用 two-phase initialization 來
延後準備物件狀態, 讓物件有機會完成初始
化 (雖然通常呼叫建構子比較合理):
#include <vector>
struct Example {
Example() {
do {
try {
v.resize(
10'000'000);
}
catch (std::bad_alloc& e) {
// do something here
}
}
while (empty(v));
// retry until success
}
std::vector<
int> v;
};
所以風格怎樣的倒不是重點, 重要的是你要知道自己在做什麼 :)
--
[P1389R1] Standing Document for SG20: Guidelines for Teaching
C++ to Beginners
https://wg21.link/p1389r1
SG20 Education and Recommended Videos for Teaching C++
https://www.cjdb.com.au/sg20-and-videos
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.216 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1606252263.A.77F.html
推 petercoin: 推一個 11/25 11:31
※ 編輯: poyenc (123.193.76.216 臺灣), 11/25/2020 11:38:46
推 s4300026: 推 11/25 17:41
推 KevinR: m 11/25 19:07
推 F04E: 推 11/26 10:17
推 deangood01: 有開優化 compiler應該還是會幫忙做 09/14 17:36