4

グローバルとしてパラメーターを使用して演算子 new を実装しようとしています。args なしの new をオーバーロードしても問題ありませんが、コンパイルしようとすると次のようなエラーが発生します。

inline void* operator new(size_t, void* p) {
    //...
    return p;
}

c:\bjarne_exercise_6.cpp(14): エラー C2084: 関数 'void *operator new(size_t,void *) throw()' には既に本体があります c:\program files\microsoft visual studio 10.0\vc\include\new( 55) : 「新しい」の以前の定義を参照してください

c:\bjarne_exercise_6.cpp(40): エラー C2264: 'operator new': 関数の定義または宣言にエラーがあります。関数が呼び出されない

これを解決したところです。#include stdafx.h の前にこれを宣言する必要があります。いいえ、そうではありません。それはうまくコンパイルされますが、まだこの関数は呼び出されませんが、新しいヘッダーファイルからのバージョンです。これは、新しい配置 (2 つのパラメーターを使用) が新しいヘッダーで既に定義されているためです。通常の new (size_t パラメーターが 1 つだけ) はそこでのみ宣言されているため、引き続きオーバーロードできます。したがって、複数のパラメーターを持つ特別な new が必要な場合は、以下の @trion によって提案されたソリューションが適切です。

4

4 に答える 4

5

この配置形式operator new(標準での呼び名) は、グローバル名前空間の C++ プログラムで既に定義されているため、自分で定義を提供することはできません。他の global とは異なりoperator new、これは置き換え可能ではありません。

于 2012-08-22T11:40:37.980 に答える
3

C ++標準は、ヘッダーファイルにoperator new追加をとる配置を定義します。その実装は次のようになります。void*<new>

void* operator new(size_t, void* m)
{
    return m;
}

これは通常、割り当てとインスタンス化を分離するSTLコンテナなどによって、すでに割り当てられているメモリ上のオブジェクトをインスタンス化するために使用されます。したがって、に依存する標準ヘッダーを含める<new>と、新しい配置がすでに定義されています。

異なるセマンティクスを使用して独自のバージョンを作成する場合operator newは、ダミーパラメータを使用して状況を明確にすることができます。

struct my_new_dummy {} dummy;
void* operator new(size_t, my_new_dummy, void* m);

//...

int mem;
int* ptr = new(dummy, &mem) int;

編集:通常の配置を再定義できるが、配置を新規に再定義できない理由operator newは、前者はデフォルトでコンパイラーによって定義され、手動でオーバーライドできるのに対し、配置新規はヘッダーで定義されるため、再定義との競合が発生するためです。 。

于 2012-08-22T11:45:00.050 に答える
3

1) グローバル レベルの配置 new 演算子を置き換えることができないため、コンパイル エラーが発生します。c++ 11 標準 (以前の標準も参照) を参照してください。

18.6.1.3 Placement forms [new.delete.placement]
1 These functions are reserved, a C++ program may not define functions that 

標準 C++ ライブラリ (17.6.4) のバージョンを置き換えます。(3.7.4) の規定は、演算子 new および演算子削除のこれらの予約配置形式には適用されません。void* operator new(std::size_t size, void* ptr) noexcept;

したがって、基本的には、他のグローバルな新しい演算子 (以下を参照) を置き換えることができますが、標準で禁止されている配置フォームは置き換えられません!

void* operator new (std::size_t size) throw (std::bad_alloc) 

2) 一方、クラス内の配置 new を含む、独自のクラス レベルの new 演算子を作成できます。これは問題ありません。

class Test
{
public:

    void* operator new (std::size_t size) throw (std::bad_alloc) {
        return malloc(size);
    }

    void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw() {
        return malloc(size);
    }

    void* operator new (std::size_t size, void* ptr) throw() {
        return malloc(size);
    }
};
于 2012-10-16T14:37:27.307 に答える
1

はい。のこの配置形式はoperator new、グローバル名前空間で既に定義されているため、自分で定義を提供することはできません。これは交換できません。

于 2013-04-24T19:13:41.077 に答える