コンパイルを防ぐことができない望ましくない C スタイルのキャストがあります。望ましくないキャストは、あるクラスのオブジェクトから他のクラスの非 const 参照への C スタイルのキャストを実行します。クラスは無関係です。同時に、同じクラスのオブジェクトから const 参照への C スタイルのキャストをサポートしたいと考えています。望ましいキャストをサポートするために、パブリック変換演算子を提供しています。この場合、望ましくないキャストを防ぐことはできないようです。
非 const 参照へのキャストはビルドに失敗し ( "Sandbox::B::operator Sandbox::A &() " (30 行目で宣言) はアクセスできません*)、const 参照へのキャストは失敗します(エラー: "Sandbox::B" から "const Sandbox::A" への複数の変換関数が適用されます: function "Sandbox::B::operator const Sandbox::A &()" function "Sandbox::B:: operator Sandbox::A &()" ):
#include <iostream>
#include <string>
#include <cstdlib>
namespace Sandbox {
class A {
public:
A (int i) : _x (i) { }
private:
int _x;
};
class B {
public:
B (const char* m) : _m (m), _a (std::atoi (m)) { }
/*
* This one shall be supported.
*/
operator const A& () {
return _a;
}
private:
/*
* This one shall be not supported.
* If this one is disabled both desired and undesired conversions pass the compilation.
*/
operator A& ();
const std::string _m;
const A _a;
};
}
int main () {
Sandbox::A a (1973);
Sandbox::B b ("1984");
/*
* This is the undesirable cast and it shall fail to compile.
*/
(Sandbox::A&)b;
/*
* This is the desirable cast and it shall pass the compilation.
*/
(const Sandbox::A&)b;
return 0;
}
演算子を無効にするoperator A& ()
と、必要な変換と不要な変換の両方がビルドされます。
gcc、icc、および MSVC コンパイルを使用しています。クライアント コードを制御できず、C スタイルのキャストを使用できません。