« 日本のソフトウェア産業を考える | メイン | 忘れやすいC++の仕様(2/3) »

 忘れやすいC++の仕様(1/3)

私は10年ほど前にC++の仕様を隅から隅まで覚えたことがあるが、それから10年、全く触っていない。Cは時々接するのでANSI Cの仕様はまだ結構覚えているが、C++の仕様は全般的にうろ覚えだ。
そんな状態で、久々にC++の仕様を眺めていると、すっかり忘れていることがいくつもあったので、ここに記す。

(1) 構造体内の構造体定義の参照

struct Outer{
	struct Inner{
	int i;
	} j;
}
というコードのInnerを参照する場合、Cだと
struct Inner i;
とできるが、C++だと
struct Outer::Inner i;
としないといけない。

(2)int値のenum型への変換
Cでは

enum Color {RED=1, GREEN, BLUE};
enum Color c;
c = 1;
ができるが、C++ではできない。
c = Color(1);
c = (Color)1;
のようにする必要がある。
蛇足だが、Cで"c = Color(1);"とすると、コンパイルエラーとはならず、Color()という関数が無いというリンクエラーになる。

(3)template文はクラス定義以外にも使える

template<class T> T square(T x)
{
	T y;
	y = x * x;
	return y;
}
のような関数定義もできる。
ひょっとしてtemplateをクラス定義にしか使えないと思い込んでいる人は少数だろうか。

(4)通常型引数と参照型引数の多重定義
C++では引数の型を変えて同じ名前の関数を多重定義できるが、

void foo(int i) {}
void foo(int &i) {}
の2つを同時に定義することはできない。
よく考えると、これらの関数を呼び分けられないので当然とも思える。
同様に
void foo(int i) {}
void foo(const int &i) {}
の組み合わせも不可だが、
void foo(int &i) {}
void foo(const int &i) {}
の2つは同時に定義できる。
なお、g++では重複定義自体はエラーにならず、呼び出し文にてコンパイルエラーとなった。

トラックバック

このエントリーのトラックバックURL:
http://ynomura.dip.jp/cgi-bin/mt/mt-tb.cgi/58

コメント (5)

KaBA:

C++の複雑な仕様の中をよく覚えてますね!
まねできないっす。。。

最近はCさえ忘れてきました。。。

もっぱらjavaで、ぬるま湯につかってます。

ynomura:

いえいえ、すっかり忘れてたってことでして…

どうでもいいですが、MovableTypeでソースコードを貼り付けるの難しいですね。preタグを使うとやたら行間が空くし、preタグを使わずにインデントを表示しようとしたら全角スペース使うくらいしかないし、そうするとcopy&pasteでコンパイルエラーになるソースになるし…
preタグ中でも"<"や">"が消えてしまうのは盲点でした。

KaBA:

C++ってホント難しいですね。
私は多重継承+friend関数で脱落しました。
でも、いろいろと応用が効きそうですね。
ynomuraさんの記事をみると。
あとは、interfaceが使えるといいのですけれど。今はどうなんですか?
演算子オーバーロードは初心者の頃、惹かれました。

私もHTMLはとっくの昔に忘れてしまいました。
pタグか、quote(?)タグはどうですか?
あ、インデントか。。。
ネストもできなかったでしたっけ?
<>は要注意っすね。

ynomura:

今回実は大学時代に取ったC++の入門書のコピーを捨てる前に読み返してたんですが、読む前は、friendって何で要るんだったっけ?という状態でした。
特に演算子のオーバーライドをする時は重要のようです。

C++はJavaと違って多重継承ができるので、インターフェースは昔から抽象クラス(仮想クラス)として記述することになってます。


class XXX_Interface{
public:
virtual void xxx() = 0;
};

class YYY_Interface{(略)};

class The_Implementer : The_Superclass, XXX_Interface, YYY_Interface{(略)};

みたいに。

HTMLでのインデントについては、結局HTML 4.01の仕様を調べたんですが、下記URLの9.1節に、preタグ以外では連続した空白は単語の区切りと解釈する、と明記されています。しかもTabは強く非推奨(9.3.4節)だそうで。
http://www.w3.org/TR/html401/struct/text.html
ネストは可能なんですが、<pre>を使った途端に行間が空いてしまいます。使ってるstylesheetのせいかも知れませんが。

というか、codeタグ(9.2節)を使ってもインデントが無視されてしまう仕様なのが、実に不思議です。

ynomura:

preタグを使うとやたら行間が空くのは、stylesheetのせいではなく、エントリーに「改行を変換する」(Convert Line Breaks)設定をした場合のMovableTypeの仕様だったようで、<pre>~</pre>の間の改行にも<br />が追加されて改行が2重になってたのが原因でした。
<pre>~</pre>等の間の改行は変換しないプラグインもあるようですが、<pre>や<table>を使うエントリーは「改行を変換する」設定にしない方が良さそうです。

コメント投稿フォーム

※投稿されたコメントはオーナーが承認するまで表示されません。


Powered by Movable Type 3.35