0

アップデート1:

ナンセンスコードを修正しました!コメントありがとうございます。最初のスニペットのハッシュを作成しました。

アップデート2:

dynamic_castの使用は回答によって不要であると指摘されているため、質問のタイトルも更新されました。

ここで達成しようとしているのは、強力な型を使用したディープコピーです。Class2をClass2の別のインスタンスにコピーできるようにしたい。ただし、ベースであるClass1のCopyTo関数も使用したいと思います。このアイデアは、私のC#の経験から生まれたもので、通常はリターンタイプをジェネリックにします(C#スニペットを参照)。

void Class1::CopyTo(Class1 *c1)
{
    // Write data in to c1 from this instance.
    c1->exampleData = exampleData;
}

// Class2 inherits Class1
Class2 *Class2::Copy()
{
    Class2 *c2a = new Class2();
    CopyTo(c2a);

    Class2 *c2b = dynamic_cast<Class2*>(c2a);
    return c2a;
}

そして、これが私がC#でそうする方法です:

public class Class1
{
    T Copy<T>()
        where T : Class1
    {
        /* Can't remember the best way to do this in C#;
         * basically if T was Class2 this would need to create
         * a new instance of that class, and the same goes for
         * Class1. */         
        T copy = createNewInstance();

        // Copy the data from this to 'copy'.
        copy.exampleData = exampleData;

        return copy;
    }
}

さて、C#スニペットと比較すると、C++スニペットは臭いを感じます。ポインタなしでこれを行うことは可能ですか、それともこの方法がベストプラクティスですか?

4

7 に答える 7

1

私はあなたが何を求めているのかはっきりしていませんが、あなたが言うときは注意してください:

 Class2 *c2 = dynamic_cast<Class2*>(c1);

キャストの結果はNULLになる可能性があるため、これを確認する必要があります。

于 2009-04-09T09:47:26.760 に答える
0

そのコードは述べられているように意味がありません...とにかく、returnとしてvoid *を使用しなかった場合は、静的キャストを使用できると「推測」しますか?

さて、コードは理にかなっています。

すでにClass2タイプの動的キャストは必要ありません。

于 2009-04-09T09:46:30.007 に答える
0

CopyTo関数では、スタック上に作成されたオブジェクトへのポインターを返します。関数が戻ると、ポインターが指すオブジェクトが破棄されるため、これは不可能です。

あなたの質問に答えて、あなたはdynamic_castポインタまたは参照で使用することができます。あなたの場合、newスタックではなくを使用して動的に返されるオブジェクトを割り当てることができます。そうすれば、ポインタを安全に返すことができます。しかし、私は潜在的なコードの臭いとして使用することを検討する傾向がありdynamic_cast、仮想関数が使用されるべきであるという兆候です。

于 2009-04-09T09:48:09.550 に答える
0

いいえ、dynamic_castはポインタと参照でのみ機能します。とにかくスタックに割り当てたものを安全に返すことができなかったので、この場合、コードをどのように変更しようとしていたのかわかりません。

于 2009-04-09T09:55:22.980 に答える
0

コードがまだあまり意味をなさないため、何を達成しようとしているのかわかりません。ただし、次のことは、あなたがやろうとしていることを概算する必要があると思います。ヒープ メモリは使用しないことに注意してください。必要ではなく、メモリ リークが発生します。

template <typename T>
T Class1::Copy()
{
    T instance;
    CopyTo(&instance);
    return instance;
}

これは、(ポリモーフィック) ポインターをinstanceCopyToメソッドに渡すため機能しますClass1

次に、次のようにコードを呼び出すことができます。

Class2 x1;
// Fill x1
Class2 x2 = x1.Copy<Class2>();

ただし、このコードは慣用的な C++ ではないため、依然として臭いがあります。C++ では、通常、代わりにコピー コンストラクターを記述します。レイト バインドCopyメソッドは存在しますが、必要になることはほとんどありません。また、上記はレイト バインドではありません (ただし、C# コードもそうではありません)。

于 2009-04-09T12:49:35.730 に答える
0

ああ、これで問題はクリアです。答えは技術的にはノーです。dynamic_cast<> ではありませんが、とにかくそれが必要な理由がわかりません。あなたが欲しいだけのようです

void Class1::CopyTo(Class1& c1)
{
    // Write data in to c1 from this instance.
    c1.SomeIntValue = SomeIntValue;
}

// Class2 inherits Class1
Class2* Class2::Copy()
{
    Class2 *c2 = new Class2();
    CopyTo(*c2);
    return c2;
}
//or more idiomatic
Class2 Class2::Copy()
{
    Class2 c2
    CopyTo(c2);
    return c2;
}
于 2009-04-09T12:51:01.390 に答える