Share via


コンパイラの警告 (レベル 2) C4250

'class1' : 優先度によって 'class2::member' を継承します

2 つ以上のメンバーの名前が同じです。 class2 内の 1 つは、このメンバーを含む他のクラスの基底クラスなので継承されます。

C4250 が表示されないようにするには、警告pragma を使用します。

仮想基底クラスは複数の派生クラス間で共有されるので、派生クラスの名前は、基底クラスの名前を支配します。 たとえば、次のクラス階層を考えると、diamond の中には func の定義が 2 つ継承されています。weak クラスを介した vbc::func() インスタンスと、dominant クラスを介した dominant::func() です。 diamond クラス オブジェクトを介した func() の修飾されていない呼び出しでは、常に dominate::func() インスタンスが呼び出されます。 weak クラスが func() のインスタンスを導入する場合、どちらの定義も支配的ではなさそうで、呼び出しはあいまいとしてフラグが設定されます。

// C4250.cpp
// compile with: /c /W2
#include <stdio.h>
struct vbc {
   virtual void func() { printf("vbc::func\n"); }
};

struct weak : public virtual vbc {};

struct dominant : public virtual vbc {
   void func() { printf("dominant::func\n"); }
};

struct diamond : public weak, public dominant {};

int main() {
   diamond d;
   d.func();   // C4250
}

次の例では C4250 が生成されます。

// C4250_b.cpp
// compile with: /W2 /EHsc
#include <iostream>
using namespace std;
class A {
public:
   virtual operator int () {
      return 2;
   }
};

class B : virtual public A {
public:
   virtual operator int () {
      return 3;
   }
};

class C : virtual public A {};

class E : public B, public C {};   // C4250

int main() {
   E eObject;
   cout << eObject.operator int() << endl;
}

このサンプルは、より複雑な状況を示しています。 次の例では C4250 が生成されます。

// C4250_c.cpp
// compile with: /W2 /EHsc
#include <iostream>
using namespace std;

class V {
public:
   virtual int f() {
      return 1024;
   }
};

class B : virtual public V {
public:
   int b() {
      return f(); // B::b() calls V::f()
   }
};

class M : virtual public V {
public:
   int f() {
      return 7;
   }
};

// because of dominance, f() is M::f() inside D,
// changing the meaning of B::b's f() call inside a D
class D : public B, public M {};   // C4250

int main() {
   D d;
   cout << "value is: " << d.b();   // invokes M::f()
}