1

私がやろうとしているのは、他のすべてのプリミティブ型と同じように動作する新しいカスタムデータ型を作成することです。具体的には、このデータ型は固定小数点の分数のように見えます。このデータ型を表す「classFixedPoint」というクラスを作成しました。その中に、「FixedPoint」から「int」、「double」、「unsignedint」などに型キャストする方法があります。これで問題ありません。

さて、キャストしたい場合はどうなり"int" to "FixedPoint"ますか?もともと私の解決策はコンストラクターを持つことでした:

FixedPoint(int i) { /* some conversion from 'int' to 'FixedPoint' in here */ }

これは機能します...しかし、次のようにユニオンに入れることはできません。

 union {
   FixedPoint p;
 };

「FixedPoint」には暗黙の自明なコンストラクターがないため、これは機能しません(コンストラクター「FixedPoint(inti)」を定義しただけです)。

cast from some type T to type FixedPoint without explicitly defining a constructor要約すると、全体の問題は「ユニオンでFixedPointタイプを使用できるようにしたい」ということです。

解決策はオンラインで証拠を見つけることができないと思います。「int」から「FixedPoint」にキャストするオーバーロードされたグローバル型キャスト演算子を定義します。

クラスコンストラクターを使用せずにこれを行う方法はありますか?このクラスをユニオンで使用できるようにしたいと思います。私が試したこと(グローバルスコープで):

operator (FixedPoint f, int a) { ... } //compiler complains about this is not a method or non-static.

そして、組合がコンストラクターを好まないことを示す小さな例(彼らはPODが好きです)

class bob
{
  public:
    bob(int a) { m_num = a; }
  private:
    int m_num;
};
void duck()
{
  union 
  {
    bob a;
  };
}

VisualStudioで見られるこのエラーは次のとおりです。

error C2620: member 'duck::<unnamed-tag>::a' of union 'duck::<unnamed-tag>' has user-defined constructor or non-trivial default constructor

何か案は?ありがとう

4

3 に答える 3

0

カスタム変換演算子は、から変換されるクラスのメンバーである必要があります。自明でないコンストラクターは必要ありません。

union編集:これはあなたが求めていたものなので、私は例を利用するように作り直しました。

EDIT2:逆の方法(構築)を行おうとしていて、コンストラクターが必要ない場合は、以下を参照してください。

#include <string>
#include <sstream>
using namespace std;

class FixedPoint
{
public:
    operator std::string() const
    {
        stringstream ss;
        ss << x_ << ", " << y_;
        return ss.str();
    }
    int x_, y_;
};

union Items
{
    FixedPoint point_;
    int val_;
};

int main()
{
    Items i;
    i.point_.x_ = 42;
    i.point_.y_ = 84;
    string s = i.point_;
}

int逆の方法(たとえば、私の例ではtoから)に行こうとしている場合、FixedPointこれを行う通常の方法は、実際に変換コンストラクターを使用することです。自明でないコンストラクターが必要ない場合は、変換関数を使用する必要があります。

FixedPoint make_fixed_point(int x, int y)
{
    FixedPoint ret;
    ret.x_ = x;
    ret.y_ = y;
    return ret;
}

union Items
{
    FixedPoint point_;
    int val_;
};


int main()
{
    Items i;
    i.point_ = make_fixed_point(111,222);
}
于 2010-09-28T20:57:28.437 に答える
0

私はあなたがこれを何のために使おうとするのか見るのに苦労しています。常にそれを確認しなければならないのは臭いようですsizeof(FixedPoint) == sizeof(int)。そして、それを仮定すると、エンディアンのような他の隠された落とし穴があります。たぶん、ここで少しバックアップする必要があります。ユニオンは、メモリのチャンクを取り、それを別のタイプとして参照するという点で、あるタイプから別のタイプに値を「変換」するだけです。すなわち

union BadConverter
{
    int integer;
    double fraction;
};

BadConverter.fraction = 100.0/33.0;
BadConverter.integer = ?;

整数が3になることはないと確信しています。これは、整数バイトがそれと共有するdoubleのメモリチャンクになります。

ユニオンは、この種のものにはあまり適していないと思われます。すべてのプリミティブ型から一連の代入演算子を定義するだけだと思います。すなわち

class FixedPoint
{
    FixedPoint& operator=(int value);
    FixedPoint& operator=(double value);
    ..etc..
    //Maybe something like this?
    template<typename T>
    FixedPoint& operator=(const T& value)
    {
        value = boost::lexical_cast<int>(value);
        return *this;
    }
}
于 2010-09-28T21:36:00.573 に答える
-2

ユニオンの一部になることを可能にするデフォルトのコンストラクターを追加することはできません。

例えば:

class bob
{
  public:
    bob(int a=0) { m_num = a; }
  private:
    int m_num;
};
void duck()
{
  union 
  {
    bob a;
  };
}

デフォルトを指定することによりa=0、それをユニオンに入れることができるはずです。でも、自分では試しませんでした。

于 2010-09-28T21:07:24.983 に答える