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;
}
さあ、こうなると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の中の別のブログに変えたいと思いますので、その時は連絡しますので興味が有る方は、そちらで合いましょう。