oF (C++)でクラス二重定義してるぞと言われないために
openFrameworksをガリガリ書いているんですが,
C++でクラスをファイル分けして書いていると,ヘッダファイルを二重インクルードしてしまいビルドが通らないなんてことがあります.
具体的に書くと
- A.h:
class hoge{}
- B.h:
#include A.h
- C.h:
#include A.h , #include B.h
こんな状態.C.hにはA.hが二度インクルードされちゃって,hogeクラスが二重定義になっているのでこのままだとエラーが出ます.
この様なエラーを解決する方法が二つあるのでそれに関して書きます.
#ifndef
#define
#endif
Xcode ver.5.1.1 で新しくC++ファイルを作成すると,一緒にヘッダファイルも作成されるんですが,デフォルトだと中身がこんな感じになってます.(例えばtestClass.hだと)
#ifndef __testClass__testClass__
#define __testClass__testClass__
#include <iostream>
//ここにクラス定義等を記述
#endif /* defined(__testClass__testClass__) */
この中の#ifndef
#define
#endif
がその二重インクルードによる二重定義を解決してくれます.
どう解決してくれるかというと,これらはC++のソースをコンパイルする前にソースに前処理をする「プリプロセッサ」に関するの記述で,
- もし
#define hoge
されていたら, #ifndef hoge
~#endif hoge
内はスキップする
という処理をしてくれます. この記述方法をインクルードガードと呼ぶそうです.便利ですね.
ただしこれより簡単な記述で同じような処理をしてくれるものがあります.
#pragma once
それが#pragma once
というコマンド(?と呼べば良いのか)です.
openFrameworks ver.0.8.1 に含まれているprojectGenerator.appで「testProject」というプロジェクトを作成すると,src
フォルダの中に
main.cpp
ofApp.cpp
ofApp.h
というファイルが作成されるんですが,ofApp.h
の中身を覗いてみると,
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
...
というように,ファイルの冒頭に#pragma once
という記述があります.
この記述がインクルードガードと同じ働きをしするんですね.もし二重にインクルードされた場合には呼び出しを無視して中身をスキップしてくれます.便利です.
技術書とかリファレンス読むの大事だな
#pragma once
は新しいコンパイラでないと対応していないため,上記二つを併記するという裏技も存在するようです.
最新バージョンのXcodeとopenFrameworksを使っているなら気にしなくても良いですね.
どの言語に関しても言えることですが,知らない人が書いたブログ上のコードをコピペして勉強するだけじゃ気づかないこと知らないまま過ごしてしまうことが多いので,本を呼んで順序よく体系立てて学ぶのは時間かかる反面理解が深まるし深く定着するので良いです.
Emmetもっと早く使い始めれば良かった
Sublime Text 3 上でEmmet使い始めました.
設定をいくつか変更しています.
デフォルトのスニペット設定[*1]だと,langがusになってるのでjaに変更.locateも同様.
*1) emmet-sublime/emmet/snippets.json at master · sergeche/emmet-sublime
Bootcamp上のWindowsの入力言語切り替えをMacの英数・かなキーでシンプルに
突然のWindows.
大学のMac(Bootcamp上のWindows使用)でWindows APIを使うプログラミングの授業をうけている際に,入力切り替えが思い通りにならないのがストレスフルだったため設定しました.
MacのJIS配列キーボードに英数・かなキーがありますが,Bootcamp上のWindowsを使っていると(おそらく)デフォルトの設定だと,英数キーで半角英数入力,かなきーでひらがな入力とシンプルな切り替えが出来ないんですよね.
設定方法(Windows 7 Microsoft IME利用 )
[テキストサービスと入力言語]>>[Microsoft IMEのプロパティ]の[編集操作タブ]から[キー設定]を変更します.
どうやらMacのJIS配列キーボードの英数・かなキーは,英数キーがWin.における「無変換キー」,かなキーがWin.における「ひらがなキー」の役割をしているようですので,その該当部分を変更します.
ぼくは単純に,無変換に[IME-オフ]を,ひらがなに[ひらがな]を適用しました.
こうすることで,英数キーを押すとIMEがオフになることで半角英数入力に,かなキーを押すとひらがな入力に変更されるようになりました.
サブディレクトリをドキュメントルートに設定する
hogehoge/
をドキュメントルートに設定したいとき.
RewriteEngine on RewriteBase / RewriteRule ^$ hogehoge/ [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)$ hogehoge/$1 [L]
上記をルートディレクトリの.htaccessに書いて, サブディレクトリ以下にあるフォルダ・ファイル名とルートディレクトリ以下にあるフォルダ・ファイル名重ならなければ正常に動作する.
# !-f は存在するファイル名にはルールを適用しない # !-d は存在するディレクトリ名にはルールを適用しない
というオプションを設定しているので, もしhogehoge/works/
とworks/
が同時に存在すると, 上記を設定していてもworks/
が表示される.
複数のMac上のDesktopフォルダを, Dropboxを利用して同期する
研究室で新しいMacbook Proを自分用マシンとして使えるようになったのですが, 自前のMacbook AirとMacbook Proを前にして, 二台の作業環境をほとんど同じようにしたら便利だろうなと思い, どう近づけようか考えてました.
SugarSyncを利用して, PC全体のファイルを同期している人もいるみたいですが, 有料サービスだし大量のファイルを同期すると負荷がかかりそう. 数分考えて, 先ほど出た答えが「DesktopフォルダだけをDropboxで同期する」でした.
僕の利用方法からして, どでかいファイルをDesktopフォルダに置くことはそう無いですし, 基本的に進行中のプロジェクトのファイルはDesktop上にあることがほとんどですので, これは良いアイディアだなということで, すぐさま設定しました.
設定方法
作業手順としては,
- Dropbox上にDesktop同期のためのフォルダを作成
- 今までDesktopフォルダ内にあったファイルをそこに入れる
- 空になった既存のDesktopフォルダを削除
- Dropbox上のフォルダのシンボリックリンクを, Desktopフォルダがあるべき場所に置く
- ログインし直す or FinderをRelaunch
以上になります.
1. Dropbox上にDesktop同期のためのフォルダを作成
こんな感じ. ファイル階層は人によって変わると思いますが, 僕は~/Dropbox/Apps/
フォルダでいくつかアプリの設定ファイルを同期しているので, そこにフォルダを作りました.
2. 今までDesktopフォルダ内にあったファイルをそこに入れる
ぽん.
3. 空になった既存のDesktopフォルダを削除
シンボリックリンクを作成する際に, 同名のフォルダがあると邪魔になってしまうので削除します.
Finder上で他のファイルのように消そうとすると, 消せないよ! と言われるので, Terminalからsudo
コマンドを利用します.
sudo rm ~/Desktop
バイバイ.
4. Dropbox上のフォルダのシンボリックリンクを, Desktopフォルダがあるべき場所に置く
下記コマンドを実行しました.
sudo ln -s ~/Dropbox/Apps/Desktop ~/
(何も考えずsudo
使用しましたが, なくてもいけるのかな? 確認していません.)
自分の環境に合わせて読み替えてください.
5. ログインし直す or FinderをRelaunch
僕の環境ではシンボリックリンクを作成しても, すぐにはDesktopにファイルが表示されなかったのでログインし直しました.
後から気づきましたが, Finderをcommand + alt + esc
からRelaunchさせれば反映されます.
-
Desktopフォルダはシステム上重要なフォルダというイメージがあるので, 途中で何かしら不具合が起きるかと思いましたが, 今のところ何も起きていないので, 安心しました.
PHPにおける文字連結は'+'ではなく'.'である
忘れてたー. しばらく'+'で繋げようとしてできなくてあれあれ?と気づかなかった. 0が出力されている時点で気づくべきだった.
$hogetext = "hoge"; $hoge3text = "hogehoge" . $hogetext;