C++ 移行ガイド | ![]() ![]() ![]() ![]() ![]() |
第 5 章
C++ 3.0 からの移行
ここでは、C++ 3.0 または 3.0.1 コンパイラ用に作成したコードを Sun WorkShop 6 C++ 用に移行するときのいくつかの注意事項について説明します。
C++ 3.0 コンパイラ以降に追加されたキーワード
C++ 3.0 コンパイラ以降に C++ に追加されたキーワードは、次のとおりです。これらのキーワードを識別子として使用している場合は、名前を変更してください。表 3-1 で説明しているように、一部のキーワードを無効にすることができます。
表 5-1 C++ 3.0 コンパイラ以降に追加されたキーワード bool、false、true
const_cast、dynamic_cast、reinterpret_cast、static_cast
explicit
export
mutable
namespace、using
typename
wchar_tソースコードの非互換性
C++ 3.0 コンパイラ用に作成したコードを Sun WorkShop 6 C++ コンパイラでコンパイルするには、次の変更が必要です。
- C++ 5.0 コンパイラでは、K&R 形式の関数定義を使用することはできません。プロトタイプ形式の関数定義を使用してください。
int f(a) int a; { ... } // エラー- 代入で
_new_handler
大域変数を設定することはできません。この目的には、set_new_handler()
関数を呼び出してください。- クラス内に
operator new()
がない場合は、常に大域のoperator new()
が使用されます。C++ 3.0 では、誤って、大域のものではなくクラスの外側のものが使用される場合があります。次の例では、C++ 3.0 は、領域の割り当てに、誤ってOuter::operator new
を使用しています。
class Outer {
public:
void* operator new(size_t);class Inner {
... // operator new なし
};
};Outer::Inner* p = new Outer::Inner; // どちらの operator new か?typedef
名を、struct
、class
、union
のタグとして使用することはできません。次に例を示します。
typedef struct { int x; } S;
struct S b; // C++ 3.0 では問題なかったが、現在はエラー
S c; // 常に OK代わりに、構造体、クラス、共用体でタグを使用してください。上記の例のエラーを解決する最も簡単な方法は、
typedef
名をさらにタグとして使用する方法です。この方法は、C でも C++ でも許可されます。
typedef struct S { int x; } S;
struct S b; // 常に OK
S c; // 常に OK
- 名前をクラス内で使用した場合、その名前を外側のスコープから定義し直すことはできません。大きな問題になる可能性があるため、C++ 標準では、そうした再定義は許可していません。C++ 3.0 コンパイラでは、このようなコードを検出しませんでしたが、現在は再定義はエラーになります。次に例を示します。
typedef int T;
class C {
T iv; // int 型
typedef float T; // T を再定義、エラー
T fv; // float 型
};このエラーを解決するには、
T
定義のいずれかの名前を変更します。
- C++ 3.0 コンパイラでは、次の例に示すように、定義されていないパラメータをとる関数へのポインタが、状況によっては、「汎用」の関数へのポインタとして機能してしまうという問題がありました。C++ の規則では、関数へのポインタの型は一致している必要があります。
typedef (*pfp)(int,char);
typedef (*ufp)(...);
int foo(int,char);
pfp p = (ufp)foo; // 3.0 では許可されたが、現在はエラー- NULL ポインタ定数でコンマを使った式を使用することはできません。リテラルのゼロは NULL ポインタ定数ですが、(anything
,0
) というような式 (anything は任意の値を示す) は NULL ポインタ定数ではありません。
int f();
char* g()
{
return (f(), 0); // 3.0 では問題なかったが、現在はエラー
// 次のようにするか、
// return (f(), (char*)0); // OK
// または次の 2 つの文にする
// f();
// return 0;
}- 基底クラスを持つクラスは、集合体の初期化構文を使用して初期化することはできません。C++ 3.0 コンパイラでは、仮想関数が存在していない場合、このことが許されていました。そうしたクラスには、コンストラクタを使用してください。
struct Base { int i; };
struct Derived : Base { int j; };
Derived d = {1, 2}; // 3.0 では問題ないが、5.0 ではエラー
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |