【GitHub】基本コマンド編
GitHub導入
テッタは、まだ開発などを進めていないのでGitHubなどは不要だと思っていたのですが、
いろいろ情報を集めていたらGitHubになれた方がいいよって情報が多いので勉強のコード管理に使ってみようと思います。
Gitの環境は依然の構築済みですので、構築方法が知りたい方は以下の記事を読んでください。
今回の記事ではGitを使うときの基本的なコマンドについて備忘録として残します。
GitやGitHubの仕組みについてはもう少し理解が進んだら別途記事にします。
各種コマンド
git configコマンド
$ git config --global user.name "XXX" # 名前の設定 $ git config --global user.email "XXX@YYY" # メールアドレスの設定 $ git config --global color.ui auto # コマンド出力が読みやすくなる設定
Git上で利用する名前とメールアドレスを設定する。
設定した名前とメールアドレスは~/.gitconfig
で確認できます。
問題なく設定できていることを確認しましょう。
git cloneコマンド
$ git clone XXXX # XXXXはGitHubのリポジトリのアドレス
git statusコマンド
$ git status
Gitの現在の状況を確認する。
git addコマンド
$ git add XXXX # XXXXはファイル名
Gitの指定のファイル状態を記録する。
git commitコマンド
$git commit -m "XXXX" # XXXXはコメント
Gitの現在の状態をコミットする。
-mはコメントを追加するためのオプションです。
git pushコマンド
$git push
Gitのコミットした内容をGitHubに反映する。
基本的な操作の流れ
GitとGitHubを使う場合の基本的な操作の流れは以下の通りです。
- 【初回のみ】git cloneコマンドを使ってGitHubのリポジトリをクローンして、ローカルPCにリポジトリを作成する。
- ファイルを編集する。
- git addコマンドを使って編集したファイル状態を記録。
- git commitコマンドでコミット。
- git pushコマンドでGitHubにリポジトリの状態を反映する。
実際の開発ではgit statusやgit diffを使い、変更内容を確認しながら、git add、git commitコマンドを使うとこになると思います。
各コマンドの詳細については他記事にまとめますので、ご参照ください。
GitHubに関連するURL
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。
興味あること
【C++】ラムダ式
ラムダ式
必要に応じてその場で定義する構文。
型類推のautoと組み合わせて使われる。
関数をその場で定義して使うことができる機能。
構文
[](parameters ...) -> return-type{
lambda-body ...
}
戻り値(return-type)の記載は省略可。
- キャプチャ有のラムダ式(デフォルト指定無し)
[variable, variable ... ](parameters ...) -> return-type{
lambda-body ...
}
キャプチャ機能とは、ラムダ式内で使いたい変数のコピーを引数の指定とは別に指定して、
ラムダ式内でコピーして使うことができる機能である。
キャプチャ機能でコピーされる変数はconst変数として扱われるので原則変更はできない。
- キャプチャ有のラムダ式(デフォルト指定無し、mutable指定)
[variable, variable ... ](parameters ...) -> return-type{
lambda-body ...
}
キャプチャした変数を変更したい場合はmutable指定をすることで修正が可能になる。
ただし、mutable指定はキャプチャ変数すべてに対して行われるので、使い方に注意が必要。
- キャプチャ有のラムダ式(デフォルト指定無し、参照をキャプチャ)
[&variable, &variable ... ](parameters ...) -> return-type{ lambda-body ... }
- キャプチャ有のラムダ式(デフォルト指定有り)
[=, variable, variable ... ](parameters ...) -> return-type{ lambda-body ... }
デフォルト指定(=)を使うことでラムダ式内で使う変数のキャプチャを自動で行う。
- キャプチャ有のラムダ式(デフォルト指定有り、参照をキャプチャ)
[&, &variable, &variable ... ](parameters ...) -> return-type{ lambda-body ... }
【C++】多種多様なコンストラクタ
コンストラクタとは
コンストラクタは、クラスをインスタンス化するときに必ず呼ばれるメソッド関数です。
その役割はクラスの情報を初期化することです。
コンストラクタの種類
コンストラクタにはいくつか種類があります。
それぞれ使い方や定義の仕方が異なるので一つずつ覚えていきましょう。
※凡例:インスタンス生成方法の記載
- Class名:class_A
- Object名:obj_A, obj_B
- 引数:x
名前 | 引数 | インスタンスの生成方法 | 説明 |
---|---|---|---|
デフォルトコンストラクタ | 無 | class_A obj_A | コンパイラが自動で生成するコンストラクタ。他のコンストラクタを定義すると自動で生成されなくなる |
引数を受け取るコンストラクタ | 有 | class_A obj_A(x) or class_A obj_A = x | 引数を受け取れるコンストラクタ。 |
コピーコンストラクタ | 有 | class_A obj_B(obj_A) | オブジェクトをコピーして新しいオブジェクトをインスタンス化するコンストラクタ。const参照でクラス自身を受け取る。 |
ムーブコンストラクタ | 有 | class_A obj_B(std::move(obj_B) | コピーコンストラクタと同様に既存のオブジェクトをもとに新しい、オブジェクトをインスタンス化する。動的かくっほしたメモリ領域の所有権を移譲するので、コピーコンストラクタより高速で動作する。 |
委譲コンストラクタ | 有 or 無 | - | コンストラクタの内部で他のコンストラクタを呼び出す方法。 |
explicit指定しの効果
「引数を受け取るコンストラクタ」は以下の2つのパターンで呼び出すことができる。
① class_A obj_A(x)
② class_A obj_A = x
どちらも「引数を受け取るコンストラクタ」の引数にxを与えてコンストラクタを呼び出しているのですが、
②のパターンについては、obj_Aにxを代入しているように見えてしまう。
このように勘違いやミスを発生させてしまうコーディングは大規模開発ではバグにつながる可能性がある。
その対策として、②のパターンのような「=」の演算子での呼び出しを禁止する方法として、
コンストラクタを宣言するときに「explicit指定子」をつけることで「=」でのコンストラクタの呼び出しをコンパイルエラーとして禁止することができる。
コード例
#include <iostream> class class_A{ int v; public: explicit class_A(int x) : v(x){} int v() const; }; int A::v()const{ return v; } int main(){ // class_A obj_A = 0; // エラー発生 class_A obj_B(10); std::cout << obj_B.v() << std::endl; }
実行結果(エラー発生個所をコメントアウトしない場合)
$ g++ test.cpp test.cpp: 関数 ‘int main()’ 内: test.cpp:16:21: エラー: conversion from ‘int’ to non-scalar type ‘class_A’ requested 16 | class_A obj_A = 0; | ^
実行結果(エラー発生個所をコメントアウトする場合)
10
まとめ
多機能なクラスほど様々な場面で使用されることが多く再利用性の高いクラスであることが必要である。
その為にも、使い方に合わせてコンストラクタを複数用意する必要がある。
ただし、各コンストラクタの特徴をつかみ場面ごとに適切なコンストラクタと定義することで初めて使いやすいクラスになる。
また、コンストラクタを複数用意する場合も必須の初期化処理については、「委譲コンストラクタ」を使ってまとめることも忘れずに!!
おまけ
C++では、「コンストラクタ」と「デストラクタ」を組み合わせることで、「必要なメモリ領域の確保」と「不要になったメモリ領域の解放」を自動的に実施する為に「RAII*」と呼ばれる仕組みがある。
「コンストラクタ」、「デストラクタ」の仕組みや機能を理解して実装することで「RAII**」をフル活用できるようになります。
ただし、動的メモリの確保や特殊なリソースについては、プログラマーが意識して解放する必要があるので、注意すること!!
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。
興味あること
【C++】VS Codeの開発環境
VS Codeで標準ライブラリのインクルードエラーが表示される
前回の記事(下参照)で、開発環境を作ったのですが、「標準ライブラリのインクルードでエラー判定される」問題が発生しています。
コンパイルはできるのですが、不要なエラー表示が出てるとコーディング時の効率化下がるので対策します。
tetta-log.hatenablog.com
※前環境では問題なかったので、Cygwin環境との連携がうまくできてない可能性があるかもしれないと、ちょっと疑ってます・・・
C/C++の設定
以下の手順で設定します。
- 「Shift + Ctrl + P」を押す
>C/C++ Edit Configurations(json)
と入力- jsonファイルを開いて以下を追加
"C:\\cygwin64\\lib\\gcc\\x86_64-pc-cygwin\\9.3.0\\include\\c++",
"C:/cygwin64/lib/gcc/x86_64-pc-cygwin/9.3.0/include/c++/x86_64-pc-cygwin",
"C:/cygwin64/lib/gcc/x86_64-pc-cygwin/9.3.0/include"
なぜ、三ついるのかは不明です。 最初に1つ目を追加したら、エラー表示で残り2つを追加するか?みたいに聞かれたので追加しました。 どれか1つ消してもエラー表示になるのでとりあえず3とも残しています。
変更前のjsonファイル
{ "configurations": [ { "name": "Win32", "includePath": [ "${workspaceFolder}/**" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE" ], "compilerPath": "C:\\cygwin64\\bin\\gcc.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "clang-x64" } ], "version": 4 }
変更後のjsonファイル
{ "configurations": [ { "name": "Win32", "includePath": [ "${workspaceFolder}/**", "C:\\cygwin64\\lib\\gcc\\x86_64-pc-cygwin\\9.3.0\\include\\c++", "C:/cygwin64/lib/gcc/x86_64-pc-cygwin/9.3.0/include/c++/x86_64-pc-cygwin", "C:/cygwin64/lib/gcc/x86_64-pc-cygwin/9.3.0/include" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE" ], "compilerPath": "C:\\cygwin64\\bin\\gcc.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "clang-x64" } ], "version": 4 }
まとめ
ツールの設定はネットを調べつつ試行錯誤で実施しているが、各設定の意味を理解していないので、応用力がつかないですね・・・
今は、調べながら先人の知恵を借りているが、自分の環境ができてくるとだんだんユニークな場面も増えるので少しずつ勉強したいですね。
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。
興味あること
Windowsを初期化したので、備忘録
Surface Pro4も限界
4年選手ぐらいになってきたSurface Pro4もいろいろな環境を入れていたせいか、 今週は一日一回落ちたり、ソフトがフリーズしたりが連発したので、初期化しました。
初期化後にC++の勉強用の環境を再構築しているので、その時の備忘録を残します。
インストールするソフト群
環境構築
VS Code
公式サイトからダウンロード。
拡張機能の「日本語化のパッケージ」と「C/C++」をインストール。
Cygwin
公式サイトからダウンロード。 インストール時のパッケージは最小限で以下の4つにしました。
- chere :VS Codeと連携するため
- wget : apt-cygをインストールするため
- pwget :wgetを使うために必要だった気がする・・・いらなかったかも
- wget-debuginfo :wgetを使うために必要だった気がする・・・いらなかったかも
apt-cygのインストール
Cygwinのパッケージ管理ソフトをインストール。
必要なパッケージが増えたときにいちいち「setup-x86_64.exe」を起動しなくていいので便利です!!
以下のサイトを参考に実施。
VS CodeとCygwinの連携
VS CodeのターミナルでCygwinを使えるように設定。
以下のサイトを参考に実施。
CygwinにGCCをインストール
C++のコンパイラのg++をインストール。
Cygwinのターミナルで以下のコマンドを実施。
$ apt-cyg install gcc-g++
恒例の「Hello World!!」を作ってコンパイルできればOK!!
CygwinにGitをインストール
Gitはwindowsにインストールする方法もありますが、開発環境はCygwinにまとめてみようと 今回初めてCygwinでインストールしてみました。 Cygwinのターミナルで以下のコマンドを実施。
$ apt-cyg install git
GitHubとの連携
GitHubでソースコード管理するためにCygwinで使えるように設定します。
以下のサイトを参考に実施。
「ターミナルをckに変更」に関してはテッタは対応しませんでした。
正しく、設定できてることを確認するために、ワークスペースで以下のコマンドを実施。
$ git clone XXX
※XXXはGitHubのURLです。クローンに成功すればとりあえずOK!!
(失敗・・・) GoogleTest環境の構築
C++の単体テスト用のツールです。 個人の勉強レベルでは不要ですが、仕事で使うことになったので、プライベートでもお試しに環境構築して、触ってみます。
いろいろ試し中でまだうまくできていなのでcygwin上でテストできるようになったら別途まとめて展開します。
ここまでの参考手順 GitHubで公開されているのでGoogleTestから最新版を持ってきましょう。
$ git clone https://github.com/google/googletest.git
以下の手順でGoogleTest用のライブラリを作成します。
- フォルダ移動
$ cd googletest/googletest
- コンパイル
$ g++ -I./include -I. -c ./src/gtest-all.cc
- ライブラリファイルの作成
$ ar -rv libgtest.a gtest-all.o
ここからテスト実行までなかなかうまくできてません・・・
まとめ
とりあえず、C++の勉強用のコードを書いてコンパイル実行までできるようになりました。
初期化前のワークスペースをWindowsの「Document」フォルダで実施していたのですが、
今回はCygwinの以下の「*C:\cygwin64\home\UserName*」をワークスペースにしました。
理由はGoogle Testなどの開発環境をCygwin内でできるだけ完結できるようにしたいと思ったからです。
開発環境やワークスペースをプロのエンジニアの方がどのように構築してるのか興味ありますよね。
いろいろ実験しながら自分の中のベストアンサー探していきます。
とりあえずGoogleTest環境を実行可能までもっていかないと・・・
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。
興味あること
【C++】const関数
const関数
constとは、ざっくりいうと「変更しない」という宣言である。
では、const関数は何を「変更しない」関数なのかというと、クラスのメンバ変数である。
要するに
cosnt関数 = クラスのメンバ変数を変更しない関数
なぜconst関数が必要なのか?
オブジェクト指向では再利用可能なオブジェクト作ることが重要である。
しかし、再利用する側の人が自分が使うオブジェクトや処理を全て理解できるかというと不可能である。
(自分が使う標準ライブラリについて、すべて熟知している人など世界でもまれだと思います。)
さらに、「自分が使うオブジェクトの処理を理解する」ということは、カプセル化というオブジェクト指向の利点を無視することになってしまいます。
なので、オブジェクト指向では使う人に見せるヘッダファイルに必要な情報を記載します。 その内の一つがconst関数のconstです。
メンバ変数を書き換える可能性がある処理ということは、中身を知らない人からすると 自分の知らないところで意図せず処理の内容が変化していまう可能性があり、使う時に注意が必要な関数です。
対して、const関数はメンバ変数書き換えることは無いので、その心配がなく気軽に使えます。
ソースコード例
#include <iostream> using namespace std; class Menmber{ int id; public: int get_id() const; void set_id(int new_id); }; int Menmber::get_id() const{ // set_id(1); // メンバ変数を書き換えるのでコンパイルエラー return id; } void Menmber::set_id(int new_id){ id = new_id; } int main(){ Menmber member1; member1.set_id(1); std::cout << "会員No." << member1.get_id() << std::endl; }
実行結果
会員No.1
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。
興味あること
【C++】thisポインタ
thisポインタとは
メンバ関数が所属するオブジェクトを指すポインタ。
thisポインタの動作確認
thisポインタは以下の振る舞いをする。
- thisポインタが指すアドレスはオブジェクトのアドレス一致する
- オブジェクトのメンバ変数に明示的にアクセスできる
「引数の変数名」と「メンバ変数名」が同じ場合にthisポインタを使うことで「メンバ変数」にアクセスできる
ソースコード
#include <iostream> using namespace std; class Sample{ private: int a; int b; public: Sample(int a, int b){ this->a = a; // 引数のaをメンバデータのaに代入 this->b = b; // 引数のaをメンバデータのaに代入 } void disp_data1(int a, int b){ cout << "【引数がある場合】" << endl; cout << "・変数名を指定" << endl; cout << "a = " << a << endl; // 引数のaを出力 cout << "b = " << b <<endl; // 引数のbを出力 cout << "・thisポインタで指定" << endl; cout << "this->a = " << this->a << endl; // メンバデータのaを出力 cout << "this->b = " << this->b << endl; // メンバデータのbを出力 } void disp_data2(){ cout << "【引数がない場合】" << endl; cout << "・変数名を指定" << endl; cout << "a = " << a << endl; // 引数のaを出力 cout << "b = " << b <<endl; // 引数のbを出力 cout << "・thisポインタで指定" << endl; cout << "this->a = " << this->a << endl; // メンバデータのaを出力 cout << "this->b = " << this->b << endl; // メンバデータのbを出力 } void disp_address(){ cout << "this のアドレス:" << this << endl; // オブジェクトのアドレスを出力 } }; int main(){ Sample sample1(1, 2); cout << "【アドレスを表示】" << endl; cout << "sample1のアドレス:" << &sample1 << endl; // sample1オブジェクトのアドレスを出力 sample1.disp_address(); sample1.disp_data1(10, 20); sample1.disp_data2(); return 0; }
実行結果
【アドレスを表示】 // 1.の振る舞いにの確認:sample1のアドレスとthisポインタが指すアドレスが同じ sample1のアドレス:0x61ff08 this のアドレス:0x61ff08 【引数がある場合】 ・変数名を指定 // 引数が出力される a = 10 b = 20 ・thisポインタで指定 // 2.の振る舞いの確認:メンバ変数が出力される this->a = 1 this->b = 2 【引数がない場合】 ・変数名を指定 // メンバ変数が出力される a = 1 b = 2 ・thisポインタで指定 // メンバ変数が出力される this->a = 1 this->b = 2
注意事項
本ページは絶賛学習中のエンジニアが自分の理解レベルで記載しています。
記載内容に誤りがある可能性があるますので、もしあれば是非コメントでご指摘お願いします。
その他同じような新米エンジニアの方で困っていることがあればテッタなりに調べますので、是非コメントください。
エンジニア仲間募集中です。