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を使っているなら気にしなくても良いですね.

どの言語に関しても言えることですが,知らない人が書いたブログ上のコードをコピペして勉強するだけじゃ気づかないこと知らないまま過ごしてしまうことが多いので,本を呼んで順序よく体系立てて学ぶのは時間かかる反面理解が深まるし深く定着するので良いです.

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 AirMacbook Proを前にして, 二台の作業環境をほとんど同じようにしたら便利だろうなと思い, どう近づけようか考えてました.

SugarSyncを利用して, PC全体のファイルを同期している人もいるみたいですが, 有料サービスだし大量のファイルを同期すると負荷がかかりそう. 数分考えて, 先ほど出た答えが「DesktopフォルダだけをDropboxで同期する」でした.

僕の利用方法からして, どでかいファイルをDesktopフォルダに置くことはそう無いですし, 基本的に進行中のプロジェクトのファイルはDesktop上にあることがほとんどですので, これは良いアイディアだなということで, すぐさま設定しました.

設定方法

作業手順としては,

  1. Dropbox上にDesktop同期のためのフォルダを作成
  2. 今までDesktopフォルダ内にあったファイルをそこに入れる
  3. 空になった既存のDesktopフォルダを削除
  4. Dropbox上のフォルダのシンボリックリンクを, Desktopフォルダがあるべき場所に置く
  5. ログインし直す or FinderをRelaunch

以上になります.

1. Dropbox上にDesktop同期のためのフォルダを作成

f:id:amuremu:20140412043441p:plain

こんな感じ. ファイル階層は人によって変わると思いますが, 僕は~/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フォルダはシステム上重要なフォルダというイメージがあるので, 途中で何かしら不具合が起きるかと思いましたが, 今のところ何も起きていないので, 安心しました.

ローカルサーバ上のWordpressで画像アップロードエラー出たとき

ローカルサーバ上で動かしているWordpressで画像アップロードしようとしたら Unable to create directory ~/dir-to-wordpress/wp-content/uploads/2014/03. Is its parent directory writable by the server? みたいなことを言われたので, Apache777権限あげました.

$ chmod 777 ~/dir-to-wordpress/wp-content/

本番環境で777はちょっとあれだけど, ローカルだし良いでしょう.
chmodコマンド初めて使った.