5

から継承するクラスがありboost::noncopyableます。たとえば、ヘッダーの抜粋を次のようにします。

class A : boost::noncopyable {
   ...
   blah
   ...
private:
   struct impl;
   boost::scoped_ptr<impl> m_impl;
};

次に、私のソリューションのプロジェクトの1つboost::noncopyableに、実装の詳細のプライベートメンバーがタイプAのオブジェクトへの参照であるクラス(たまたまから継承する)があります。たとえば、ヘッダーの抜粋で:

class B : boost::noncopyable {
   ...
   blah
   ...
private:
   struct impl;
   boost::scoped_ptr<impl> m_impl;
};

および実装の抜粋 (cpp) では:

struct B::impl {
    impl(A& a) : m_a(a) {}
    set_A(A& a) {m_a = a;}
    A& m_a;
    ...
}

B(A& a) : m_impl(new impl(a)) {}
...

次に、私のソリューションの別のプロジェクトでは、B から継承するクラス C を、ヘッダーの抜粋とともに使用します。

class C : public B {
   ...
   blah;
   ...
private: 
   struct impl;
   boost::scoped_ptr<impl> m_impl;
};

および実装の抜粋 (cpp) では:

struct C::impl {
    impl(A& a) : m_a(a) {}
    void set_A(A& a) {m_a = a;}
    A& m_a;
};

C(A &a) : B(a), m_impl(new impl(a)) {}
...

しかし、MSVC++ 2008 でビルドしようとすると、次のエラーが発生します。

error C2248: 'boost::noncopyable_::noncopyable::operator =' : cannot access private member declared in class 'boost::noncopyable_::noncopyable'
see declaration of 'boost::noncopyable_::noncopyable::operator ='
error C2248: 'boost::scoped_ptr<T>::operator =' : cannot access private member declared in class 'boost::scoped_ptr<T>' with T = A::impl
This diagnostic occurred in the compiler generated function 'A& A::operator =(const A&)'

コンパイラは、set_AB ではなく、C の機能にのみ問題がありset_Aます。誰かがこれについて何か考えを持っていて、光を当てることができるかどうか感謝しますか? いつもご関心をお寄せいただきありがとうございます。

編集:

要約すると、ここで私が理解していないのは、なぜコンパイラがエラーに関するエラーをいつ適用するかについてうるさいのかということですboost::noncopyableset_A(..)クラス Cの関数をコメント アウトすると、すべて正常にコンパイルされます。しかし、それを保持するとエラーが発生しますが、クラス B では同じ問題はありません。詳細を示すために、上記のエラー メッセージを少し編集しました。ここで、コンパイラが生成した関数について何かを述べていることに注意してください。なんらかの理由でこれがクラス C でのみ発生した可能性はありますか? なんで?

4

1 に答える 1

6

[編集]

まず第一に、あなたの質問をよりよく理解できるようになりましたが、実装を次のように変更したくない理由はまだわかりません。

struct C::impl {
    impl(A& a) : m_a(&a) {}
    void set_A(A& a) {m_a = &a;}
    A* m_a;
};

コピー不可の場合、これAは単純に機能しません。

void set_A(A& a) {m_a = a;}

ともかく:

このエラー:

エラー C2248: 'boost::scoped_ptr::operator =': クラス 'boost::scoped_ptr' で T = A::impl で宣言されたプライベート メンバーにアクセスできません

boost::scoped_ptr<T>コピーできないためであり、この事実はAクラスがコピーできないという事実とは関係ありません。

このエラー:

この診断は、コンパイラによって生成された関数 'A& A::operator =(const A&)' で発生しました。

機能の1つが原因であることは確かですXXX::set_A(A& a) { m_A = a; }。そのような関数A::operator =(const A&)では必須です - そしてそれが定義されていないので、コンパイラはデフォルトのものを定義しようとします。デフォルトの one はメンバーを 1 つずつコピーし、メンバーの 1 つはコピーA不可boost::scoped_ptr<A::impl>です。

次に、あなたにとって最も重要な質問-なぜ両方のXXX::set_A(A& a) { m_A = a; }方法ではなく、1つのエラーだけですか?

私のg ++​​ 4.5.x環境であなたのケースの簡易版をテストしました。診断はあなたのものと非常に似ています-そして効果は非常に似ています-1つのset_A機能だけが不平を言っています-最初の機能です。これはA& operator = (const A&)、両方に必要なためですが、最初のものに対してのみ生成されます。g++ は優れた診断を提供します。

../src/AnExample.cpp:24:32: note: synthesized method 'A& A::operator=(const A&)' first required here

私の例と診断:

class noncopyable {
private:
   noncopyable(const noncopyable&);
   noncopyable& operator = (const noncopyable&);
};

class A {
  noncopyable m;
};

class B {
  B(A& a) : a(a) {}
  void set_A(A& a) { this->a = a; } // line 24
  A& a;
};

class C {
  C(A& a) : a(a) {}
  void set_A(A& a) { this->a = a; }
  A& a;
};

make all 
Building file: ../src/AnExample.cpp
Invoking: Cygwin C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/AnExample.d" -MT"src/AnExample.d" -o "src/AnExample.o" "../src/AnExample.cpp"
../src/AnExample.cpp: In member function 'A& A::operator=(const A&)':
../src/AnExample.cpp:15:17: error: 'noncopyable& noncopyable::operator=(const noncopyable&)' is private
../src/AnExample.cpp:18:9: error: within this context
../src/AnExample.cpp: In member function 'void B::set_A(A&)':
../src/AnExample.cpp:24:32: note: synthesized method 'A& A::operator=(const A&)' first required here 
make: *** [src/AnExample.o] Error 1
src/subdir.mk:18: recipe for target `src/AnExample.o' failed
于 2012-09-21T11:58:30.677 に答える