C++ 移行ガイド | ![]() ![]() ![]() ![]() ![]() |
第 2 章
互換モードの使い方
この章では、C++ 4 コンパイラ用に記述されたコードをコンパイルする方法について説明します。
互換モード
-compat
-compat=4
example%CC -compat -O myfile.cc mylib.a -o myprog
以降で説明するように、互換モードにおいては、C++ 4 と Sun WorkShop 6 C++ コンパイラの間に多少の使用方法の違いがあります。
互換モードで有効なキーワード
互換モードでは、新しい C++ キーワードの一部がキーワードとして認識されます。ただし、これらのキーワードの大部分は、次の表に示すようにコンパイラオプションを使用して無効にすることができます。しかし、コンパイラオプションを使用するよりも、ソースコードを変更してこれらのキーワードを使用しないようにすることをお勧めします。
表 2-1 互換モードで有効なキーワード explicit
-features=no%explicit
export
-features=no%export
mutable
-features=no%mutable
typename
なし
typename
キーワードを無効にすることはできません。表 3-1 に示すその他の新しい C++ キーワードは、互換モードではデフォルトで無効になります。言語の意味
Sun WorkShop 6 C++ コンパイラでは、C++ 言語の一部の規則について適用機能が強化されています。旧式の構文に対する基準も厳しくなっています。
新しいバージョンの C++ コンパイラをリリースする際に、旧式の構文のサポートを中止するということは、以前からの方針 (マニュアルに記載) でした。しかし、C++ 4 で旧式の構文に関する警告を有効にしてコンパイルすると、かなり前の C++ コンパイラでは受け入れられてきたが、実際には不正であったコードが見つかることがあります。旧式の構文とは主として、アクセス規則 (非公開や限定公開) に違反した構文や、型一致規則に違反した構文、コンパイラが生成した一時変数を参照パラメータの対象として使用した構文などです。
コピーコンストラクタ
オブジェクトを初期化するとき、あるいはクラスの型の値を渡したり返したりするとき、コピーコンストラクタはアクセス可能でなければならない。
class T {
T(const T&); // 非公開
};
void f1(T t) { } // エラー、T が渡されない
T f2() { T t; return t; } // エラー、T が返されない解決策: コピーコンストラクタをアクセス可能にしてください。通常は、公開にします。
static
記憶クラス
static
記憶クラスは、型ではなくオブジェクトおよび関数に適用される。
static class C {...}; // エラー、ここでは static を使用できないstatic class D {...} d; // OK、d は static になる解決策: この例では、クラス C の
static
キーワードは意味がないので削除してください。
operator
new
とoperator
delete
new
でオブジェクトを割り当てるときは、対応するoperator delete
がアクセス可能でなければならない。
class T {
void operator delete(void*); // 非公開
public:
void* operator new(size_t);
};
T* t = new T; // エラー、operator delete にアクセスできない解決策: 演算子
delete
をアクセス可能にしてください。通常delete
は公開アクセスであると想定されています。クラスメンバーでない
operator new
またはoperator delete
をstatic
宣言することはできない。
static void* operator new(size_t); // エラー
- 解決策: 関数を大域型にしてください。
delete [5] p; // エラー、delete [] p;
を使用すること
new
const
const
オブジェクトをnew
で割り当てる場合は、オブジェクトを初期化する必要がある。
const int* ip1 = new const int; // エラー
const int* ip2 = new const int(3); // OK条件式
C++ 標準は条件式の規則に変更を導入しました。Sun WorkShop 6 C++ コンパイラは、標準モードと互換モードの両方で新しい規則を使用します。詳細は、「条件式」を参照してください。
デフォルトのパラメータ値
多重定義演算子や関数へのポインタにデフォルトのパラメータ値を設定することはできない。
T operator+(T t1, T t2 = T(0) ); // エラー
void (*fptr)(int = 3); // エラー解決策: 他の方法でコーディングする必要があります。一般的には、関数または関数へのポインタ宣言を追加することが考えられます。
main()
の戻り値の型
void main(){ ... } // エラー解決策:
main
の戻り値の型をint
にしてください。return
文を追加する必要はありません。追加した場合、return
文はint
値を返す必要があります。末尾にコンマを使用する
f(int i, int j, ){ ... } // エラー
const
値またはリテラル値を渡す
const
以外の参照パラメータにconst
値またはリテラル値を渡すことはできない。
void f(T&);
extern const T t;
void g() {
f(t); // エラー
}解決策: 上記の関数によってパラメータが変更されない場合は、
const
を参照するようにconst
宣言 (この例ではconst T&
) を変更してください。関数によってパラメータが変更される場合、パラメータにconst
やリテラル値を渡すことはできません。代りに、const
以外の一時変数を明示的に作成し、それを渡します。詳細は、「文字列リテラルと char*」を参照してください。関数へのポインタと
void*
間の変換C++ コンパイラは互換モードと標準モードのどちらでも、
+w2
オプションが指定された場合に、 関数へのポインタとvoid*
間での暗黙的および明示的変換に対して警告を出します。 コンパイラは、どちらのモードでも、多重定義された関数呼び出しを解釈処理するときには、暗黙的な変換を認識しません。詳細は、「関数ポインタと void*」を参照してください。
enum
型
enum
型のオブジェクトを初期化したり、enum
型のオブジェクトに値を代入する場合は、その値もenum
型でなければならない。
enum E { one = 1 };
E e1 = 1; // エラー、int で E を初期化することはできない
E e2 = E(1); // キャストで解決マクロの再定義
#undef
を間に入れずにマクロを別の値に再定義することはできない。
#define count 1
#define count 2 // エラー解決策:
#define
文の一方を削除するか、2 つ目の#define
文の前に#undef count
文を挿入してください。メンバー初期化リスト
メンバー初期化リスト中に暗黙の基底クラス名を入れる旧式の C++ 構文を使用することはできない。
struct B { B(int); };
struct D : B {
D(int i) : (i) { } // エラー、B(i) を使用すること
};
const
とvolatile
修飾子関数に引数を渡すとき、および変数を初期化するとき、ポインタに対する
const
とvolatile
修飾子は正しく対応している必要がある。
void f(char *);
const char* p = "hello";
f(p); // エラー、const ではない char* に const char* を 渡すことはできない解決策: ポイント先の文字列が関数によって変更されない場合は、パラメータを
const
char*
で宣言してください。ポイント先の文字列が変更される場合は、文字列のconst
ではないコピーを作成して、そのコピーを渡してください。入れ子の型
クラス修飾子がないと、包含するクラスの外側から入れ子の型にアクセスすることはできない。
struct Outer {
struct Inner { int i; };
int j;
};
Inner x; // エラー、Outer::Inner を使用することクラステンプレートの定義と宣言
クラステンプレートの定義と宣言中では、山かっこ
< >
で囲まれた型引数が付いたクラスの名前は無効でしたが、バージョン 4 とバージョン 5.0 の C++ コンパイラはエラーを報告しませんでした。たとえば、次のコードでは、MyClass
に付けられた<T>
は定義と宣言のどちらでも無効です。
template<class T> class MyClass<T> { ... }; // 定義template<class T> class MyClass<T>; // 宣言解決策: 次の例のように、山かっこで囲まれた型引数をクラス名から削除します。
template<class T> class MyClass { ... }; // 定義template<class T> class MyClass; // 宣言テンプレートコンパイルモデル
互換モードでのテンプレートコンパイルモデルは 4.2 のコンパイルモデルとは異なります。新しいモデルについての詳細は、3-6 ページの 3.3.5 節「テンプレートレポジトリ」を参照してください。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |