0

メソッド内で、クラスから初期化されていないオブジェクトを作成できますか?

ここにいくつかのコンテキストがあります: コンストラクターがすべてメモリを割り当てるクラスを想像してください:

class NumberArray
{
  size_t m_Size;
  int *m_Numbers;

public:
  NumberArray() { m_Size = 1; m_Numbers = new int[1]; m_Numbers[0] = 0; }

  // . . . other methods for manipulating or constructing . . .

  ~NumberArray() { delete[] m_Numbers; }

  // What if I had a method that concatenates two arrays?
  NumberArray ConcatenateWith(const NumberArray &) const;
};

このようなメソッド内では、 class の初期化されていないオブジェクトを作成し、次にパラメーター内のオブジェクトにNumberArray基づいて新しいオブジェクトを「構築」したいと思うでしょうか? this別名:

NumberArray NumberArray::ConcatenateWith(const NumberArray &other) const
{
  // Mystery manner of creating an uninitialised NumberArray 'returnObject'.
  returnObject.m_Size = m_Size + other.m_Size;
  returnObject.m_Numbers = new int[returnObject.m_Size];
  std::copy(m_Numbers, m_Numbers + m_Size, returnObject.m_Numbers);
  std::copy(other.m_Numbers, other.m_Numbers + other.m_Size, returnObject.m_Numbers + m_Size);
  return returnObject;
}

これを行う最善の方法は何ですか?基本的に、デフォルトのコンストラクターでサイズ 1 の配列を作成したくありません。これを削除してから、とにかく新しい配列を再度割り当てます。

4

4 に答える 4

1

あなたが求めているのは、新しい配置です。これは次のようになります。

#include <cstdlib>
#include <new>

void* mem = std::malloc(sizeof(T)); // memory for a T (properly aligned per malloc)

T* x = new (mem) T; // construct a T in that memory location
x->~T();            // destruct that T

std::free(mem); // and free the memory

これを正しく(適切に管理および調整されたメモリを使用して例外安全な方法で)行うことは、簡単な作業ではありません。オブジェクトの寿命に注意する必要があります。

あなたの質問のために、あなたは正確に何をしているのかを説明してstd::vectorいます。初期化されていない生のメモリを割り当て、挿入された要素をそのメモリに直接構築します。そして、そのコードの多くは、ライフタイムとメモリ管理を正しくし、例外を安全にすることに専念しています!

std::vector自分で書くのではなく、使用することを強くお勧めします。

于 2013-02-05T01:35:52.917 に答える
1

何をしようとしているのかは完全には明らかではありませんが、クラスの新しいインスタンスを作成し、デフォルトのコンストラクター以外のコンストラクターを呼び出さないことだけが必要な場合は、それを実行してください。

あなたがしなければならないのはprivate、デフォルトのコンストラクターとは異なる署名を持ち、メモリを割り当てないコンストラクターを作成することです(または、デフォルトのコンストラクターとは異なるために必要な方法が異なります)。次に、必要に応じて、クラスにそのコンストラクターを内部的に呼び出すだけです。

于 2013-02-05T00:30:03.693 に答える
0

私の知る限り、コンストラクターを呼び出さずにオブジェクトを作成するための明確な方法はありません。これは、パブリックインターフェイスにアクセスできるかどうかには関係ありませんが、呼び出すことができるユーザーを制限する場合は、プライベートコンストラクタまたは保護されたコンストラクタを実装できます。独自の内部メソッドからクラスの新しいインスタンスを作成することに制限はありません。実際、オブジェクトを制限する場合は、オブジェクトのインスタンスを作成するプライベートコンストラクターと静的パブリックメソッドを定義するのが一般的です。作成することができます。

必要に応じて、オブジェクトに十分なメモリを割り当て、そのメモリへのポインタを必要なタイプのポインタにreinterpret_castすることができます。これは通常PODで機能しますが、c ++でのポリモーフィック継承の多くの実装(すべてではないにしても)は、ポリモーフィックインスタンスへのvtableへのポインターを追加するため、このアプローチは通常、常にではないにしても、それらに対して失敗します。

つまり、プライベートコンストラクターを作成し、静的メソッドでそれを呼び出してから、必要なその他の作業を実行することをお勧めします。

于 2013-02-04T20:49:56.980 に答える
0

私はこれがあなたが望むもの、ある種の「匿名」クラスに似ているかもしれないと思います:

struct test {
    virtual void doSomething() {
        puts("test");
    }
};

struct a {
    test *t() {
        struct b : test {
            void doSomething() {
                puts("b");
            };
        };

        return new b;
    };
};

int main()
{
    a a;

    a.t()->doSomething(); // outputs 'b'
}

ただし、スライスとnewC ++での動作により、関数のみに制限されている場合でも、ポインターを返す必要があり、「匿名」型には名前を付ける必要があります。

OPを編集して、これによって達成したいことを正確に明確にすることができれば、私たちはもっとあなたを助けることができるかもしれません。

于 2013-02-04T21:05:06.520 に答える