2016-09-05 11 views
12

誰かがこのC++コンパイルエラーの性質を説明できますか?私は、グローバルオペレータの新規、削除、およびその変形を過負荷にすることについて勉強中です。私はcoupleofarticlesonthesubjectを読んで、私はこれを具体的に対処するためと思われるものを見つけることができませんでした。C++演算子new/delete/variantがヘッダファイルに含まれていないのはなぜですか?

コード

foo.h

#ifndef foo_h 
#define foo_h 

void* operator new(size_t); 
void* operator new[](size_t); 

void operator delete(void*); 
void operator delete[](void*); 

#endif // foo_h 

foo.cpp

#include <foo.h> 
#include <iostream> 

void* operator new(size_t size) { return NULL; } 
void* operator new[](size_t size) { return NULL; } 

void operator delete(void* p) { } 
void operator delete[](void* p) { } 

コンパイルエラー

>g++ -g -std=c++14 -I./ -c foo.cpp -o foo.o 
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39, 
       from foo.cpp:2: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:116:41: error: declaration of ‘void operator delete(void*) noexcept’ has a different exception specifier 
    __attribute__((__externally_visible__)); 
             ^
In file included from foo.cpp:1:0: 
./foo.h:8:6: error: from previous declaration ‘void operator delete(void*)’ 
void operator delete(void* p); 
    ^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39, 
       from foo.cpp:2: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:118:41: error: declaration of ‘void operator delete [](void*) noexcept’ has a different exception specifier 
    __attribute__((__externally_visible__)); 
             ^
In file included from foo.cpp:1:0: 
./foo.h:9:6: error: from previous declaration ‘void operator delete [](void*)’ 
void operator delete[](void* p); 
    ^

私が思うに、この問題に関するいくつかの奇妙は関連しています。私はfoo.cpp#include <iostream>をコメントアウトした場合、私はfoo.hに関数の宣言をコメントアウトし、唯一のそれらの定義を保持する場合

  • 、コンパイルが
  • を成功し、 foo.cpp(さらには#include <iostream>を保持)では、コンパイルは成功します。

私はいくつかの漠然とした疑いを持っています。おそらく回答がその答えを経由して確認します:

  • エラーがexception specifierの言及はので、私はこれらの演算子のいずれかをオーバーライドすることによって、多分考えになり、私は彼らの兄弟のスイート全体を上書きすることが義務付けています。ただし、operator delete(void*, const std::nothrow_t&)の宣言と定義を追加しても、コンパイルエラーは変更されませんでした。私はまた、これらの演算子のいずれかをオーバーライドすると、コーダーはそれらのすべてを実装することを義務付けているが、それを誤解しているのは当然ではないと思いますか?
  • 私は、これらの演算子は一つだけ「翻訳単位」に含まれている必要があり、したがって、ヘッダファイルであってはならないことを言及するのStackOverflowの外側の記事を読みました。私は翻訳単位が何であるか分からず、その記事はそれが何であるかを説明しなかった。これはすべて私の前にC++コーディングの経験に反しているようだ - それがこの問題に関連している場合は、「翻訳単位」は、なぜそれがヘッダファイルから関数宣言の除外が必要かを説明してください。

は、任意の洞察力をいただき、ありがとうございます。

答えて

5

あなたが見ている問題は、次の宣言の違いによるものです。

void operator delete(void*); 
void operator delete [](void*); 

の代わりに自分の中でそれらを宣言する:あなたは、それらを宣言しながら

void operator delete(void*) noexcept; 
void operator delete [](void*) noexcept; 

ライブラリはとしてoperator delete関数を宣言します。あなたが主題についての詳細は、それへのアクセス権を持っている場合、Hファイルは、あなたがC++ 11標準の

#include <new> 

ルックアップセクション18.6動的なメモリ管理を使用する必要があります。

通常、翻訳単位は.cppファイルです。詳しい読書:What is a "translation unit" in C++

+1

あなたの答えは、コンパイラのエラーが実際に私に問題の内容を正確に伝えていることを実感しました。もっと精査してくれないと悪いですが、ありがとうございます。あなたの答えは、私がギャップを埋めるのを助けました。 – StoneThrow

+0

私は同じエラーを再現することができず、問題に投稿された全く同じコードをコピーしたので、奇妙です。それが本当に問題なら、なぜ私はエラーを受けていませんか? btw、私はVS 2015を使用しています。 –

+0

@MuhammadAhmad、なぜあなたは何のエラーも出ていません。それは検索する価値があります。 –

関連する問題