Xcode [コンピュータ言語]


最近Objective-Cを学習しているのですが、その中でC++の強化が有るようです。Xcode4 versionでのアップルのプロモーションビデオを見てもC++に触れていて、多くの操作が出来るようになった事を、促しています。

そこでにわかにどう強化されているのか、調べる事にしたのですが、ネット上にあるサンプルリストは、大概がウインドウズかUNIXなので、だめなのかなと思いきや、そうでもなさそうです。

私のOSのバージョンはMac OS X 10.6.8、Xcode3.2.6 64-bitです。前のバージョン迄動作しなかったと思ったのですが簡単なものであれば、普通に動作するようです。ただし、最初だけ気を付けなければならないようです。C言語での scanf() やC++の cin >> はアップルのデバッガコンソールからではちょっと工夫しなければなりません。

これはリンクフリーから抜粋したコードですが”きじねこ”というホームページからです。


#include <iostream>

#include <complex>

using namespace std;//ここで宣言しておけば下文はstd::は省略可能


int main()

{

std::complex<double> value;

std::cin >> value;

//実数を入力したら最後に&を付ける

std::cout << std::abs(value) << std::endl;

return 0;

}


これをデバッガコンソールから実行すると、待ち受け画面からDOSのように抜け出られません。又日本語も入力できません。でも諦めないで下さい。こうすればよいのです。最後に & をつけるとDOSのようになりました。又日本語を入力するときは、あらかじめコピーしておいて、ペーストすると入力できました。何故かは分からないのですが、&はANDのビットフラグでしたっけ?ただコンパイル済みのUNIX実行ファイルをターミナル上で実行するときは普通に実行できますので、初めからそちらで試した方が良いようです。


さあ、こうなるとXcodeでは出来ない操作を変換するだけで良さそうです。ある解説書には、仮想関数、コンストラクタやデストラクタは使えないそうです。ので、逃げ道がちゃんとあるようです。

これは私が買った本のサンプルコードからの抜粋ですが、作者の林 晃氏も著作権侵害と言えないくらいの抜粋です。ほんの名前は、「Objective-C 逆引きハンドブック」です。


class MyClass {

public:

    MyClass() {

        _str = nil;

    }

    

    virtual ~MyClass() {

        [_str release];

    }

    

    // Objective-CのクラスのインスタンスをC++のメソッドの引数として使える

    void DoSomething(NSString *newStr) {

        if (_str != newStr)

        {

            [_str release];

            _str = [newStr copy];

        }

        NSLog(@"%@", _str);

    }

    

private:

    // Objective-Cのクラスのインスタンスをメンバー変数として使用できる

    NSString *_str;

};

・・・

これは丸っきりC++の構文なのですが、違うのはrelease, copyでしょうか。C++であれば、newとdeleteを使う訳ですが、objective-C++では型をオペランドに取れないから駄目なそうです?

なのでメッセージ式で、[_str release], [newStr copy]とすれば問題解決と言う訳です。

試しに10年以上前のCodeWarriorのサンプルを試してみましょう。作者はデーブ・マークです。日本語が今は使えますから、出力文字を日本語に直しておきます。コードは、WhatAmI.cppです。ステーショナリーは、最初にC++stdc++ Command Line Toolです。WhatAmI.mmでも大丈夫のようです。


#include <iostream.h>


//---------------------------------------  Shape


class Shape

{

// Data members...

// Member functions...

public:

virtual void WhatAmI();

};


void Shape::WhatAmI()

{

cout << "私はどんな種類の形か知りません!\n";

}


//---------------------------------------  Shape:Rectangle


class Rectangle : public Shape

{

// Data members...


// Member functions...

public:

void WhatAmI();

};


void Rectangle::WhatAmI()

{

cout << "私は長方形です!\n";

}


//---------------------------------------  Shape:Triangle


class Triangle : public Shape

{

// Data members...


// Member functions...

public:

void WhatAmI();

};


void Triangle::WhatAmI()

{

cout << "私は三角形です!\n";

}


//---------------------------------------  main()


int main()

{

Shape *s1, *s2, *s3;

s1 = new Rectangle;

s2 = new Triangle;

s3 = new Shape;

s1->WhatAmI();

s2->WhatAmI();

s3->WhatAmI();


return 0;

}


さあ、どんなエラーが出て来るでしょうか。とりあえずやってみます。?

昔のコードですが警告一つで、問題なく完了しました。のメッセージです。今初めて試してみたのですが、以前は出来なかったと思いました。 結果は、

This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000

プログラムをデバッガに読み込み中...

プログラムは読み込まれました。

run

[Switching to process 2227]

実行中...

私は長方形です!

私は三角形です!

私はどんな種類の形か知りません!


Debugger stopped.

Program exited with status value:0.


警告は以下、

#ifdef __DEPRECATED

#warning This file includes at least one deprecated or antiquated header. \

読んで行くと、instead header<iostream.h>とありますので<iostream>変えてみます。が、今度は3つのエラーが出て来てだめです。この警告は問題の無い警告のようです。

取り合えず、全てのサンプルは動作しそうです。

今度はObjective-C++でコードを変換してやってみました。WhatAmI2.mmと言うファイルを作ります。ステーショナリには無いようなので、後でmをmmに名称変更すれば++を認識できるみたいです。中身はこう、


#import <Foundation/Foundation.h>


class Shape : public NSObject {

public:

Shape() {NSLog(@"私はどんな種類の形か知りません!\n");}

virtual ~Shape() {NSLog(@"オブジェクトは破棄されました\n");}

};


class Rectangle : public Shape {

public:

Rectangle() {NSLog(@"私は長方形です!\n");}

~Rectangle() {NSLog(@"オブジェクトは破棄されました\n");}

};


class Triangle : public Shape {

public:

Triangle() {NSLog(@"私は三角形です!\n");}

~Triangle() {NSLog(@"オブジェクトは破棄されました\n");}

};


@interface MyObject:NSObject {

Shape *_shape;

Rectangle *_rectangle;

Triangle *_triangle;

}


- (void)message;

@end


@implementation MyObject


- (void)message

{

_shape = new Shape();

delete _shape;

_rectangle = new Rectangle();

delete _rectangle;


_triangle = new Triangle();

delete _triangle;


Shape c1;

}


@end


int main(int argc, char **argv)

{

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

MyObject *myObject = [[MyObject alloc] init];

[myObject message];

[myObject release];

[pool drain];

return 0;

}


取りあえずコンパイルは出来ました。結果は以下、


run

[Switching to process 383]

実行中...

2011-07-17 07:26:50.636 WhatAmI2[383:a0f] 私はどんな種類の形か知りません!

2011-07-17 07:26:50.638 WhatAmI2[383:a0f] オブジェクトは破棄されました

2011-07-17 07:26:50.638 WhatAmI2[383:a0f] 私はどんな種類の形か知りません!

2011-07-17 07:26:50.638 WhatAmI2[383:a0f] 私は長方形です!

2011-07-17 07:26:50.639 WhatAmI2[383:a0f] オブジェクトは破棄されました

2011-07-17 07:26:50.639 WhatAmI2[383:a0f] オブジェクトは破棄されました

2011-07-17 07:26:50.639 WhatAmI2[383:a0f] 私はどんな種類の形か知りません!

2011-07-17 07:26:50.639 WhatAmI2[383:a0f] 私は三角形です!

2011-07-17 07:26:50.640 WhatAmI2[383:a0f] オブジェクトは破棄されました

2011-07-17 07:26:50.640 WhatAmI2[383:a0f] オブジェクトは破棄されました

2011-07-17 07:26:50.640 WhatAmI2[383:a0f] 私はどんな種類の形か知りません!

2011-07-17 07:26:50.641 WhatAmI2[383:a0f] オブジェクトは破棄されました


Debugger stopped.

Program exited with status value:0.

これを見ればコンパイラーがどう読んでいるかよく分かります。又これは参考であり、私自身は置き換えただけなので、もっと良い方法が有るのかも知れません。

只、C++には膨大な遺産が埋もれています。アップル首脳陣もここは迷うところではないでしょうか。特に科学計算などはそうです。またこれにアップルの得意なGUIが加味されれば、未来の科学技術、シュミレーション技術に貢献する事請け合いです。私自身勉強中であり、これに関する資料は皆無です。でもこれが将来的に有望だと確信したいと思います。

最近は、これに専念したいので、So-netの中の別のブログに変えたいと思いますので、その時は連絡しますので興味が有る方は、そちらで合いましょう。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。