컴파일러 경고(수준 2) C4250
'class1': 지배를 통해 'class2::member'를 상속합니다.
둘 이상의 멤버의 이름이 같습니다. class2
하나는 이 멤버를 포함하는 다른 클래스의 기본 클래스이므로 상속됩니다.
C4250을 표시하지 않으면 경고 pragma를 사용합니다.
가상 기본 클래스는 여러 파생 클래스 간에 공유되므로 파생 클래스의 이름이 기본 클래스의 이름을 지배합니다. 예를 들어 다음 클래스 계층 구조가 지정된 경우 다이아몬드 내에서 상속된 func의 정의에는 약한 클래스를 통한 vbc::func() 인스턴스와 주 클래스를 통한 dominant::func()의 두 가지 정의가 있습니다. 다이아몬드 클래스 개체를 통한 func()의 정규화되지 않은 호출은 항상 dominate::func() 인스턴스를 호출합니다. 약한 클래스가 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()
}