Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaとかC#とか最近の言語使いのためのC++入門

まりも
May 20, 2024
44

 JavaとかC#とか最近の言語使いのためのC++入門

C++は古いCとの互換性を保っており、C使いがその習慣そのままプログラムを書くことも多いため、古い印象がありますが、非常にモダンなプログラムの書き方にも対応している言語です。最新のC++ではポインタなどは全く使わないことが推奨されていそうなレベルです。モダンな言語を知っている人の観点から、C++の紹介をします。

まりも

May 20, 2024
Tweet

Transcript

  1. 極めて高級な言語の普及 C++は比較的低級なので難し く感じる Ruby とか C#と か Java とか 2

    初めて学習する言語が極めて高級であることが増えてきている
  2. メモリ管理(クラス) • スコープで解決できない問題 – オブジェクト指向では、データが塊としてツリー上 に確保される – ツリーの枝は、最初に確保したプログラムのあず かり知らぬところで増えたり減ったりする •

    クラスを使って解決(RAII) – メンバ変数にポインタを利用していなければ、ス コープと同じように破棄される – ポインタの参照先は、自インスタンスが破棄され る時に、子インスタンスを責任を持って破棄する 8
  3. メモリ管理(スマートポインタ) • クラスで解決できない問題 – 戻り値などで、オブジェクトの外に出されるオブ ジェクトはクラスでは管理できない • スマートポインタ(std::shared_ptr) – 参照カウンタ方式で、使われなくなったら自動的

    にガベージコレクト 9 shared_ptr<ofstream> getStream() { return make_shared<ofstream>("C:¥test.txt"); } いっそこれだけしか使わない ことにすれば、C#やJavaと ほぼ同じになります。
  4. ポインタ(その他) • まれに、これまで挙げた手段が使えない場合 もあります – 引数に関係ない – 配列や文字列ではない – ポインタ演算は行わない

    – メモリ管理に関係ない • ポインタの難しい部分を全く使わないので、 心配せずにポインタを使いましょう 15
  5. Cの機能 • かなり高度なことはできます 18 C標準ライブ ラリ 型シ ステ ム 構造

    体 列挙 体 共用 体 C++の新しい機能に置き換えられているものも多いので、 できるだけそっちを使いましょう
  6. ジェネリックプログラミング • 同じvectorクラスがfloatにもstringにも使え、 型チェックも行われます。 21 vector<double> vf { 0.3, 0.2,

    0.1 }; vf.push_back(0.4); sort(begin(vf),end(vf)); double f = vf[0]; vector<string> vs { "CCC", "BBB", "AAA" }; vs.push_back("DDD"); sort(begin(vs),end(vs)); string s = vs[0];
  7. 型推論 • オブジェクトの生成時に力を発揮します 23 map<string, vector<int>> m; vector<int> v; v.push_back(1);

    v.push_back(2); v.push_back(3); m["A"] = v; v.clear(); v.push_back(4); v.push_back(5); m["B"] = v; v.clear(); v.push_back(6); v.push_back(7); v.push_back(8); v.push_back(9); m["C"] = v; map<string, vector<int>> m { {"A", {1, 2, 3}}, {"B", {4, 5}}, {"C", {6, 7, 8, 9}} };
  8. 高階関数 char* data[] = {"Apple", "Microsoft", "Google", "Oracle", "Dell"}; char

    deleted = 'O'; resultNum = 0; for(i = 0; i < dataNum; i++){ /* 頭文字がbad以外のもののみを結果として抽出 */ if(data[i][0] != deleted){ result[resultNum++] = data[i]; } } /*文字列数でソート*/ for(i = 0; i < resultNum; i++){ for(j = i + 1; j < resultNum; j++){ if(strlen(result[j]) < strlen(result[i])){ tmp = result[i]; result[i] = result[j]; result[j] = tmp; } } } CREATE TABLE #DATA (S VARCHAR(MAX)) INSERT INTO #DATA(S) VALUES('Apple'), ('Microsoft'), ('Google'), ('Dell'), ('Oracle') DECLARE @DELETED CHAR SET @DELETED = 'O' SELECT S INTO #RESULT FROM #DATA WHERE SUBSTRING(S, 1, 1) <> @DELETED ORDER BY LEN(S) C Transact-SQL 24 CとSQLで、同じ処理を書いてみます Cの書き方と比べ、SQLの方が分かりやすいですね
  9. 高階関数 • ほかの色々な言語で書いてみます data = %w(Apple Microsoft Google Dell Oracle)

    deleted = "O" result = data .find_all{|s| !s.start_with? deleted} .sort{|l, r| l.size <=> r.size} Ruby var data = new[] { "Apple", "Microsoft", "Google", "Oracle", "Dell" }; var deleted = "O"; var result = from s in data where !s.StartsWith(deleted) orderby s.Length select s; var data = new[] { "Apple", "Microsoft", "Google", "Oracle", "Dell" }; var deleted = "O"; var result = data .Where(s => !s.StartsWith(deleted)) .OrderBy(s => s.Length); Dim data = New String() {"Apple", "Microsoft", "Google", "Oracle", "Dell"} Dim deleted = "O“ Dim result = From s In data Where Not s.StartsWith(deleted) Order By s.Length Select s C# C# (メソッド構文) Visual Basic 最近の言語は、CよりSQLに近い形で書けるものが多いです。 $data = array('Apple', 'Microsoft', 'Google', 'Oracle', 'Dell'); $deleted = 'O'; $result = array_filter($data, function($s) use ($deleted){return substr($s, 0, 1) != $deleted;}); usort($result, function($l, $r){return strlen($l) - strlen($r);}); PHP 25 List<String> data = Arrays.asList("Apple", "Microsoft", "Google", "Oracle", "Dell"); String deleted = "O"; Stream<String> result = data.stream() .filter(s -> !s.startsWith(deleted)) .sorted((l, r)->l.length() - r.length()); Java data = ['Apple', 'Microsoft', 'Google', 'Dell', 'Oracle'] deleted = 'O' result = [x for x in sorted(data, key=len) if not x.startswith(deleted)] Python @data = qw/Apple Microsoft Google Dell Oracle/; $deleted = "O"; @result = sort {length $a <=> length $b} (grep /^[^$deleted].*/, @data); Perl
  10. 高階関数 • さらにいろいろ (def data ["Apple" "Microsoft" "Google" "Oracle" "Dell"])

    (def delete ¥O) (sort #(< (count %)(count %2)) (filter #(not (= (first %) delete)) data)) Clojure data = ['Apple', 'Microsoft', 'Google', 'Oracle', 'Dell'] deleted = 'O' result = (s for s in data when s.charAt(0) != deleted) result.sort (l, r) -> l.length - r.length CoffeeScript var data = ['Apple', 'Microsoft', 'Google', 'Oracle', 'Dell']; var deleted = 'O'; var result = data.filter((s) => !s.startsWith(deleted); result.sort((l, r) => l.length - r.length); Dart let data = ["Apple"; "Microsoft"; "Google"; "Oracle"; "Dell"] let deleted = "O" let result = data |> List.filter(fun s -> not(s.StartsWith(deleted))) |> List.sortBy(fun s -> s.Length) F# 26 |data deleted result| data ← #('Apple' 'Microsoft' 'Google' 'Dell' 'Oracle'). deleted ← 'O'. result ← data select:[:s | (s beginsWith: deleted) not]. result ← result sortBy:[:l :r | (l size) < (r size)]. Smalltalk var data = "Apple" :: "Microsoft" :: "Google" :: "Oracle" :: "Dell" :: Nil var deleted = "O" var result = data filter(!_.startsWith(deleted)) sortWith(_.size < _.size) Scala let data = ['Apple', 'Microsoft', 'Google', 'Oracle', 'Dell']; let deleted = 'O'; let result = data.filter(s=>s.charAt(0) != deleted); result.sort((l, r)=>l.length - r.length); JavaScript var data = ['Apple', 'Microsoft', 'Google', 'Oracle', 'Dell'] var deleted = 'O' var result = data.filter(s=>s.charAt(0) != deleted) result.sort((l, r)=>l.length - r.length) TypeScript
  11. 高階関数 • もっといろいろ 27 let data = ["Apple", "Microsoft", "Google",

    "Oracle", "Dell"] let deleted = "O“ var result = data.filter({ !$0.hasPrefix(deleted) }) result.sort({count($0) < count($1)}) Swift let data = ["Apple", "Microsoft", "Google", "Oracle", "Dell"]; let deleted = "O"; let mut result : Vec<&&str> = data.iter().filter(|s| !s.starts_with(deleted)).collect(); result.sort_by(|l, r|l.chars().count().cmp(&r.chars().count())); Rust auto data = ["Apple", "Microsoft", "Google", "Oracle", "Dell"]; const deleted = 'O'; auto result = data.filter!(s => s[0] != deleted).array; result.sort!((l, r)=>l.length < r.length); D val data = array("Apple", "Microsoft", "Google", "Oracle", "Dell") val deleted = 'O' val result = data.filter{it[0] != deleted} sortBy{it.length} Kotlin NSArray *data = [NSArray arrayWithObjects:@"Apple", @"Microsoft", @"Google", @"Oracle", @"Dell", nil]; NSString *deleted = @"O"; NSIndexSet *filteredIndexes = [data indexesOfObjectsPassingTest: ^(id obj, NSUInteger idx, BOOL *stop){return (BOOL)![obj hasPrefix:deleted];}]; NSArray *result = [[data objectsAtIndexes:filteredIndexes] sortedArrayUsingComparator: ^(id l,id r){ NSNumber *lLength = [NSNumber numberWithUnsignedInteger:[l length]]; NSNumber *rLength = [NSNumber numberWithUnsignedInteger:[r length]]; return [lLength compare:rLength]; }]; Objective-C $data = 'Apple', 'Microsoft', Google', 'Oracle', 'Dell' $deleted = 'O' $result = $data | ?{$_ -notlike "$deleted*"} | Sort-Object Length Powershell
  12. 高階関数(C++) vector<string> data { "Apple", "Microsoft", "Google", "Oracle", "Dell" };

    auto deleted = 'O'; auto newEnd = remove_if(begin(data), end(data), [&](auto s) { return s[0] == deleted; }); data.erase(newEnd, end(data)); sort(data.begin(), data.end(), [](auto l, auto r) { return l.size() < r.size(); }); 28 • C++では
  13. 標準C++ライブラリ 入出力 文字列 string 正規表 現 数値処理 複素数 分数 言語支援

    例外 一般 時間 スマート ポインタ STL(Standart Template Libraly) コンテナ イテレー タ アルゴリ ズム 30
  14. 標準C++ライブラリ(std:string) • 文字列クラス – 普通に多機能です – C文字列との相性もばっちり 34 string s

    = "ABC"; s = s + "DEF"; s.replace(2, 2, "XYZ"); int si = s.size(); const char* c = s.c_str();
  15. 標準C++ライブラリ(コンテナ) • std::vector – 配列の代わりに利用できる • std::map – 連想配列 35

    vector<int> v = { 1, 2, 3 }; v.push_back(4); int i = v[2]; map<string, double> m; m["A"] = 1.3; m["B"] = 2.5;
  16. constexpr • コンパイル時実行 39 constexpr int fib(int n) { return

    n == 0 ? 0 : n == 1 ? 1 : fib(n - 2) + fib(n - 1); } int main() { constexpr auto fib20 = fib(20); }
  17. 機能が多すぎる弊害 • 可読性が悪くなる 44 C C++ C# - - -

    STRUCT_A a; STRUCT_A *a = malloc(sizeof(STRUCT_A)); ClassA a; ClassA *a = new ClassA; shared_ptr<ClassA> a = make_shared<ClassA>(); ClassA a = new ClassA();