Aug 10, 2007

忘れやすい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++では重複定義自体はエラーにならず、呼び出し文にてコンパイルエラーとなった。



Posted at 21:23 in PC一般 | WriteBacks (5)
WriteBacks

C++の複雑な仕様の中をよく覚えてますね! まねできないっす。。。 最近はCさえ忘れてきました。。。 もっぱらjavaで、ぬるま湯につかってます。

Posted by KaBA at 08/12/2007 11:42:34 AM

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

Posted by ynomura at 08/13/2007 10:04:03 PM

C++ってホント難しいですね。 私は多重継承+friend関数で脱落しました。 でも、いろいろと応用が効きそうですね。 ynomuraさんの記事をみると。 あとは、interfaceが使えるといいのですけれど。今はどうなんですか? 演算子オーバーロードは初心者の頃、惹かれました。 私もHTMLはとっくの昔に忘れてしまいました。 pタグか、quote(?)タグはどうですか? あ、インデントか。。。 ネストもできなかったでしたっけ? <>は要注意っすね。

Posted by KaBA at 08/14/2007 08:36:47 PM

今回実は大学時代に取った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節)を使ってもインデントが無視されてしまう仕様なのが、実に不思議です。

Posted by ynomura at 08/16/2007 08:49:18 AM

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

Posted by ynomura at 02/12/2008 11:28:33 PM

writeback message: