FC2ブログ

次の日常:exist, コマンドライン引数, クラスのpublicにルール?, sstream

if(exist(<引数>)){
continue;
}
なんてしてみると英語で読んだとおりにかけるのだなぁと感心.ただ,実装してるときにはわかりづらい.
こういう書き方をするには当然bool exist(<引数>); で定義すればよいですね.まだboolを自分で使うには抵抗があったけど,
使ってみようかな.


int main(int argc, char* argv[]){
なんて始まるのをいつだか学んだんですが,この引数のことをコマンドライン引数と呼ぶのですね.ううーん.毎回勉強が浅いのかも…


引き継いだC++のプログラムには,ちょっとしたルールを課して作ってあるように見えました.
それは,クラスのpublicなメンバ関数は,他のpublicな関数を参照しないというものです.
意図を汲んでみると,おそらく,publicな関数はクラス外部から定義できてしまうので,それにより望みの機能が意図的であれ故意であれ変わってしまわないようにしているのではないかと.

どれだけ一般なのかわかりませんし,使えるルールなのかはわかりません.小さい実装だからこそ可能なルールかもしれません.
なにかよく知っている方がいればコメントくれるとありがたいです(まだこのブログ成熟どころか卵ですらないんですがね…写真とか写真とか異様に小さい写真とか).


vectorが使えるといいなぁなんて昨日投稿しましたが,同じように,
sstreamをincludeしてostringstreamとかistringstreamとか定義しちゃって,がんばろうと思いました.
文字列苦手ですし.簡単にはto_stringなんてある…みたいな記述も見かけた.
スポンサーサイト



ちょっと日常:三項演算子a?b:c, 列挙体enum, vector, クラスの継承・純粋仮想関数

日常なのであんまり真剣に読まないでね.


突然出てきたらびっくりします.三項演算子.疑問に思う…のがよいかもしれないな.
ただの<条件> ? <真の実行式> : <偽の実行式>
です.これがif()の中にそのまま現れたのです.最初なにかと思いました.
三項演算子?キモッッて中学の頃に見た覚えがあったからすんなり理解できたわけで…


逆に最近にちょっとした記事で見ただけの知識,それが生きたのは列挙体に関して.
列挙体は

enum <識別子> {<要素1>, <要素2>, …} <変数名>;
enum hand {left, right} person;
と書きます.
全然知りませんでした.ちょっと恥ずかしい.
識別子と変数名のどちらかは省略可能.え?意味わかんない…と思ったけど

考えた結果,識別子はクラス名のようなもので,そのクラスの構造を持つものをいろいろ用意できる…いや,だから識別子なんですけど.こっちは容易に理解できるし,私の見たenumもこれだった.変数名はクラスを定義した後に変数を作るのと同じ感覚.
じゃあ識別子を書かないって?役割を持たせた列挙体を一つに限って用意したいとき(があるのか・・?),実現できます.他に使い道は浮かばないので,どう使うかが問題の気がします.

そもそものenumの使い方?中身?としては,例えばhand::leftと書いてみたりするんですが,leftにはint型の0が,rightにはint型の1が列挙変数に関連付けられています.とはいえ,hand = 0;とするのは定義されておらず,hand = (enum hand) 0;という形が標準です.暗黙の型キャストはコンパイラ依存と言えます.
また,switch文ではswitch(hand) { case: left …と書くことができる.


vectorが使えたら私もデータ処理とか楽しめるんじゃないかと思って,やり始めました.
結果はでてないけど.
とりあえずvector.push_backでデータを一個追加することができると知ったよ.どう追加されてるのさ…
一次元データがどう格納されて,push_backやpop_backは最後尾で行われるかとか,そういう点を理解しなきゃいけない.
あと二次元データの扱い方があればそこも勉強しなきゃ.


さて,まとめたかったクラスの継承.そういうものがあるっていうことだけは知ってたけど,まとめて読んだのは初めてだった.

・クラスの継承は":"でおこなう.: public <親クラス名>とかprivate <親クラス名>とか.
親クラスのpublicメンバ関数をpublicで継承したいときにpublic指定,privateで継承したいときにprivate指定するだけ.
・メンバ変数を初期化して継承するには<親クラス名>に続いて","を置いて,<メンバ変数1>(<値1>), <メンバ変数2>(<値2>),…としていく.
・virtualでメンバ関数を仮想関数に.すると継承した子クラスで再定義ができるようになる.
・純粋仮想関数virtual <メンバ関数名> = 0; 関数の実体を定義せず,継承される前提で仕組みを内包させておく使い方だろうか.
・抽象クラスとは,純粋仮想関数などを使って実体を作らないクラス.実体を作れない…そのことを「インスタンス」という言葉を使っていたけど私にはまだわからなかったな.
・public,privateの他にprotectedというものがある.親クラスで使って,その時点ではprivateと同じだが,継承クラスでpublic扱いで継承される.
・他にも,子クラスのpublic内でusing <親クラス名>::;なんてすると親クラスで定義しつつも使えないようにしてあった関数を,親クラスで行った実装を引き継いで使うことができます.これはちょっとした発見だったな.
・あと,親クラスのデストラクタはvirtualにしとかないとね,と.
・他には,this->ってなんだよ!とか.いや,そのままなんですけどね.クラスの実装の中で,メンバ変数をいじるときにthis-><メンバ変数名>と書く・・はず.


こんなとこかな.うーん,文にしてまとめるには多すぎるし何より教科書的な内容だから箇条書きのままで.
それでは.

Qtでプロジェクトを引き継いだときの諸問題の解決

統合開発環境初心者(IDEってコレダヨネ)がQtのプロジェクトを引き継いで運用することになりました.
運用って言っても内輪で使う程度のもので,現状で完成してるから引き継ぎできるよう維持していってという程度なのだけど.

そんな私が早速維持できずに,スタックしたわけです.悲しい.

PCに関してはWin10, 64bit程度だけ言えばいいですかね.

まず,Qtをインストールします.そこからスタック.
全く気づかずに,QtのうちVS2015でコンパイルする版をインストール.しかし私のPCにはすでにVS2017がインストール済み.
2015に戻る必要もないのにインストールしたモノ自体に目がいかず,なんでコンパイルできないのーなんてただやって1週間.
アホですね.

気づいて,QtのMinGWのやつをインストールし直す.
Qt Creatorを起動.とりあえずコンパイルぽい動きはしてくれた.
早速エラー.なんだろう.なんだ…これは…
(時刻): ディレクトリ "C:\Users\~~~\" Util.asciify("build-(ソフトの名前)-Desktop_Qt_5_6_2_MinGW_32bit-unknown")" でエラー: TypeError: Property 'asciify' of object Core::Internal::UtilsJsExtension(0x35fb720) is not a function" を作成できませんでした
と出る.これはすぐ解決して,Qt Creatorの左タブにある「プロジェクト」で,
debugでもreleaseでも,シャドウビルドのチェックボックスを切っておく.

そして,47個のエラーを吐きながらも,exeファイルを生成してくれた.前任者もそのまま残していったエラーだろうと踏んで,exeの実行にかかる.
さあ,exeを実行してみよう(release版を実行するけど,debug版でやると後ろにdが付いたdllファイルを言われるよ).
エラー.
Qtエラー
こんな感じってよくありますよね・・で,
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
libgcc_s_dw2-1.dll
をまず最初に言われます.
この点に関して,似た記事はこちら.
うぇぶとらばぁす 作ったアプリケーションの実行
どこにあるのかな,と探すとインストールしたQtのフォルダの中にあります.
ちなみに,私がやった順で説明しますと
C:\Qt\Qt5.6.2\Tools\QtCreator\bin
C:\Qt\Qt5.6.2\Tools\mingw492_32\bin
から引っ張ってきて,exeのあるフォルダにコピーしました(QtとMinGWのインストールしたバージョンはフォルダ名の通りです).
これが…実は間違いだったのですが.続けて,実行すると
libstdc++-6.dll
libwinpthread-1.dll
が足りないよといいます.Qt系じゃないのでMinGWにあるだろうと思って探してちゃんとあります.同じくコピー.
さあ実行.
え?技術的に私が及ばなそうなエラーが来ました.
プロシージャ エントリ ポイント _Z4endlR11QTextStreamがダイナミック リンク ライブラリ
C:\Users\~~~\(実行したexeファイル名) から見つかりませんでした。
ちょっと頭が働いた私はダイナミックリンクライブラリがdllだということに気が付きます.しかしこれは,結果的にヒントになりませんでした(正しいわけですが).ずっと空回りして1週間を費やしたのです.
結論を先にいいますと,dllを取ってくるフォルダが間違っていたというものです.正しくは
C:\Qt\Qt5.6.2\5.6\mingw49_32\bin
から取ってくればよいです.すると正しく実行できます.この記事を読む人は,すぐ解決できるでしょう.
ちなみに,exe実行時の初めのエラーを検索した方は,Toolsのフォルダからコピーすればいいという記事を見つけるはずです.それは間違っている…少なくとも私の例ではそうなりますので,お気をつけて.
なぜ2種類あるのか…実は2種類以上あるんじゃないのか…という問題ですが,これはかんたんに言えばdll hell(dll地獄,dependency hell)という事柄のようです.

dllを取ってくるフォルダの違いに気づかなかった私は,エラー自体の理解やらQt Creatorでのコンパイルし直しなどをいろいろ試します.
そこら辺のエラー内容などを全てまとめておくので,吸い寄せられるようにここにきて解決する人がいるといいなぁと思います.

まず,エラーについてです.
私にはプロシージャエントリポイントなんてわかりませんが,つまりは,
dll(今回は実行したexeファイルそのもの)内に_Z4endlR11QTextStreamなんて関数はないよ,dllに入ってるって君(実行者?)は言うけど入ってなかったよ
ということのようです.このエラー自体はとてもよく起きるようで,dll hellと強く関連します.

一例だけ,理解したレベルで紹介してみます.
dllはライブラリを動的にリンクするものです.dllに入っているような処理内容を実行ファイルごとに全て入れる必要がなくなり,省スペースであるという点が重要です.一軒家に家族人数分のトイレがあったら家は窮屈です.1つくらいのトイレをみんなが必要なときに参照するのがいいでしょう.地区に役所が個々人の人数分設立されていたらとてつもない無駄です.dllはそういうものだと簡単に理解しています.
そんなdllですが,例えば内部に間違い,プログラムで言えば欠陥が存在すれば,直して更新せざるを得ません.以前のdllのバージョンと互換性があればよいですが,互換性がなかった場合に問題がおきます.
古いdllで開発されたものが,新しいdllを参照してプログラムを動かし,互換性のない部分に触れた場合.よくてエラーして終了です.悪ければブルースクリーンやそれ以上にでもなるんじゃないでしょうか(そのくらいの感覚でdllを触ったほうがよいという意味です).

今回,dllを入れ替えただけで直ったんですが,なぜエラーの示したものがdllではなくexe実行ファイル本体だったのか,私には結局わかりませんでした.exeにということはdllでななくc,cppやhファイルかと思ったんですけどね…

次に,Qt Creatorでコンパイルし直してみると何が起きるのか,書き残します.
デバグ開始します.
実行失敗
During startup program exited with code 0xc0000139.
とポップします.
また,そんな状況で「実行」をしてみます(Qt Creatorの左タブ下の方のやつです).
アプリケーション出力に
C:\Users\~~~\(ファイル名).exe を起動中...
プログラムが突然終了しました。
C:\Users\~~~\(ファイル名).exe がクラッシュしました。
と出力されます.
なぜこうなるのだろう,という推測です.
dllを読み込むには環境変数を使っているでしょう.その優先順位が,Qt Creatorでの実行時,通常実行時とで共に現在のフォルダ(exeファイルのあるフォルダ)が初めの方にあるのだと考えてます.誰かチェックして.
持論を続けますと,Qt Creatorで実行するときには,ソフトが例えば
..\
C:\Qt\Qt5.6.2\5.6\mingw49_32\bin
C:\Qt\Qt5.6.2\Tools\QtCreator\bin
C:\Qt\Qt5.6.2\Tools\mingw492_32\bin
という優先順位でdllを探索してくれてるとか.そんでもって通常実行時にはC:\Qt\らへんのなんて参照してないとか.
だから通常実行時に「オイ.dllねえぞコノヤロウ」と言ってきて,私が間違って優先順位の低い方からdll引っ張ってきたばかりに,その後ではQt Creatorでも通常実行でも起動しなくなる(プロシージャエントリポイントのエラー)のではないか,と考えます.

実際,環境変数を調べてみるとシステムのも含めQtフォルダのものはありませんでした.
%SystemRoot%がどーのこーの言ってる海外のフォーラムもあったけれど…知らない…なにそれ.多分関係ないんじゃない?

持論を支えるにはもう2つくらいチェックする項目あるけど,誰かチェックして.
1.dllのバージョンチェック
2.Qt Creatorでコンパイル・実行時のdllやheader,cpp等を読み込む設定

力尽きた.参照したサイトが載っていないのは,今回ほんとにいろんなところを探索しすぎてきりがなかったから.
あ,ちなみにプロシッジャエントリポイットのエラーのときに,dllが足りないのでは??と考えて,dependency walkerというのも試しました.
exeファイルが参照するdllを読み込んでくれるソフトです.更新がされておらずAPI-WIN-??系だかなんだかを認識してくれないという問題はありますがそれはdependency walkerと共にネットですぐ知れます.それをチェックした上で,足りないものはなかったわけです.それでdllのバージョン違い,という問題に対処することを思いつきました.

dependency walkerの使い方のレクチャー(英語) How to generate Dependency Walker log files for Customer Support
Qt Creatorの使い方のレクチャー(英語) C++ Qt 84 - User Feedback how to deploy an application
両方共youtubeですが,見てません.そんな英語力まではないです.後者を見ることで解決したというフォーラム(こちら)は有りました.

この件,あまりにもフォーラムが少ない.日本語も英語も.なぜか勝手に直って捨ててるスレが数件あるというのも問題….

int main(void)とデストラクタ~とexternを知る

C/C++を高濃度に触ることになり困惑中.
そもそもわかんないよね,なんて思ってる部分を再確認.
mainの引数,戻り値は?
https://oshiete.goo.ne.jp/qa/2445252.html
ただの知恵袋.
答えは,
int main(void)
int main(int argc, char *argv[])
で.前者は引数キニシナーイ.後者は,argument countとargument valueの並び.
https://teratail.com/questions/7310
によると,argcで引数の数を示し,argvで引数に書いてあることを読んでるみたい.そう受け取った(仕様読めよ)
class Hoge{
public:
Hoge(){
----;
};
----;
~Hoge();
}
つまり私はclassの勉強不足なんですよ.
疑問に思ったことは,~Hogeってなに,でした.
なんで同じ名前のやつのチルダがあるの.ははは…;

https://www.s-cradle.com/developer/sophiaframework/tutorial/Cpp/ctordtor.html
クラスオブジェクトが作られる際,はじめに実行されるのがpublic内にあるHoge().これ,コンストラクタ.
一方で,クラスオブジェクトが捨てられる際に実行されるのが~Hoge().こっちがデストラクタ.
引数は指定できても戻り値はない.あっても困る気がする…
簡単に言えば,コンストラクタは初期化,デストラクタは後始末なのだから,うまく行ったかどうか以外に戻り値に意味はないし.

いや,うまく行ったかどうかって大事だけど…boolとかで大事に扱ってるのを知ってはいるけど…コンパイル時点で問題があるか判別してくれてたりしないかな.class内なのだし.コンパイラでのチェックは容易そう.それを理由として戻り値がない,とかであってほしい.

そんなこんな調べてるうちにこんな記事.
http://d.hatena.ne.jp/u_1roh/20091108/1257673753
引用
むしろ、次のようなコードがC/C++への「入り口」としてふさわしいんじゃないか。

extern "C" {
__declspec(dllexport) int HelloWorld() { return 0; }
}
え?
全くわかりません.

とりあえず一時しのぎとして,extern "C"ぐらいは調べました.
http://d.hatena.ne.jp/debian36/20080227/1204109794
マングリングを防ぐのに使われる,という記事.
なんかちがう.多分焦点のずれた記事を読んでいるのだろう.

ということで,またの機会に.

VS2015からVS2017Communityに変えたときのエラー対処

C++のプログラムを諸事情によりわざわざVS2017に変更.
めんどくさいけれどやらないとことは進まない.そんな,変更作業のメモ.

まずは2017Communityへの変更点.が,MSDNライブラリで公開されてる.
https://msdn.microsoft.com/ja-jp/library/bb531344.aspx
当然公開されているけど,初めてこういうの読んだ.

後に紹介するサイトが私の問題とほぼ近いけど,先にこのライブラリを読んでの注記だけしちゃおう.
数学関数のヘッダmath.hに変更が.

cmathで多くのオーバーロードを定義していたが,以前はmath.hにもオーバーロードの定義があった.
今回の変更で,cmathのみでオーバーロードを定義,math.hでは一切定義しないようになった.

ということで,数学関数の類はいろいろ問題が起きそうなわけですね.
特にfloat, long doubleはmath.hからcmathへの移動が起きています.

さて,現在生じている問題点…
ほぼ似たものがあったので,それを引用.
https://stackoverflow.com/questions/42777424/visual-studio-2017-errors-on-standard-headers

つまりは数学系のincludeで某起きてる.それに引き続いてfloat型の様々な数学関数の定義がごしゃっとしてる.全部cmathの中身でエラーしてて,絶対私のせいじゃない.そんなのはどうでもいいとしてアンサーを見る.
Windows Universal CRT SDK
を個別のコンポーネントとしてインストールすること.
ふむ.エラーが1つだけになった.
インストールしたUCRTは何なのか…いつ私にわかるだろうか.全然読み解けない.
えっと…このサイトは関係あるのかな…
https://docs.microsoft.com/ja-jp/cpp/porting/upgrade-your-code-to-the-universal-crt

最後のエラーはMSB8036.単に説明に
Windows SDK バージョン 8.1 が見つかりませんでした
とあるのでそれを入れてみる.
コンパイルが通りました.

…合計で1GBくらい消費してるんだけど…こんなでいいのかな…
ということで終わりです.

終わらなかった.
プログラムを実行してみると,msvcr120d.dllがないとうるさい.
これはでも検索するとすぐ出て来る.debugバージョンを使ってるのが悪い,だそうです.
とりあえずreleaseバージョンで実行して事なき.当然検索したサイト参照したけどちょっと気分悪いから引用書かない.
今度こそ終わり.

ついでにSDKとAPIの違いをかるく勉強した.
このサイト,面白かったよ.はっちゃけてて.
http://tom-rc.hatenablog.com/entry/2014/12/10/232830

またの機会に.

計算でいっぱいだ

inlineは今は考えなくていい
デストラクタも,constメンバ関数も
complexのpolarメンバ関数って引数doubleなんだ,すげーつかえねーー… って,単にexp使えばよかった.
テンプレートやんなくていい



Complexクラス自作しよう http://d.hatena.ne.jp/white_wheels/20100321/p1
  あまり普通じゃない?読めない
VC++でM_PIを使うには http://tech.ckme.co.jp/cpp/cpp_pi.shtml
  解決済み
externとモジュール https://www.grapecity.com/tools/support/powernews/column/clang/015/page03.htm
  解決済み
ソースファイルの分割 http://www.kushiro-ct.ac.jp/yanagawa/ex/1-tg/05/index.html
  ほぼ解決
行列計算ライブラリBlitz http://taichino.com/programming/4183
  興味
クラスの使い方 http://bituse.info/cp/3
  メモリ動的確保など
complexクラスについて http://133.31.121.94/complex.html
  complexについて,使える関数がかるーく………え,このサイトの情報どっから来てんだ,私の環境で使えないのなんでだ
手を動かしてさくさく理解する C言語/C++ ポインタ入門 http://vivi.dyndns.org/tech/cpp/pointer.html
  ポインタがんばらないとねー
2次元配列とポインタ http://www.asahi-net.or.jp/~uc3k-ymd/Lesson/Section02/section02_04.html
  ポインタがんばらないとねー(2回目)
++C++ 未確認飛行C http://ufcpp.net/study/csharp/oo_property.html
  …C#でした…(気づけよ),このサイトの他のページにあったpartial classもたぶんC++にはないんだろな…
complex double を float にコピーできない http://homepage2.nifty.com/well/CantCopyComplex.html
  古い記事.テンプレートを勉強するころに読んでみたい.

1.#QNAN関連
  http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1441137454
  http://stackoverflow.com/questions/4617796/1-qnan-error-c
  http://www.c-tipsref.com/words/not_a_number.html

ポインタ

自分用まとめ.p156-

int a=0;
int *p;
p= &a;
cout << p << endl;
cout << &a << endl;
a = 1;
cout << a << endl;
cout << *p << endl;
*p = 2;
cout << a << endl;

int& r = a;
r = 3;
cout << a << endl;
cout << *p << endl;

int *q1, *q2;

p165-
プロフィール

satsuki

Author:satsuki
記事を消しつつ、ころころ変えながら運用中

最新記事
最新コメント
月別アーカイブ
カテゴリ
訪問者数
検索フォーム
リンク
QRコード
QR