앞으로 선언하고 포인터를 사용 하 여 수신
-
20-09-2019 - |
문제
고 싶을 확인하는 유형의 수퍼 클래스 A
에 대한 유형의 서브 클래스 B
(는 방법을 내부의 수퍼 클래스 A
, 록 B
이 상속).
여기에 무슨 생각은 속임수를 썼는지(즉,사용 앞으로의 선언문):
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
};
class B : public A {
public:
double d_;
};
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
그러나 이 코드를 컴파일되지 않습니다.오류가:
main.cc: In member function ‘void A::Check()’:
main.cc:12: error: invalid use of incomplete type ‘struct B’
main.cc:6: error: forward declaration of ‘struct B’
어떻게 이 문제를 해결하는가?
해결책
당신이 해결하려는 문제는 가상 방법에 의해 훨씬 더 잘 처리된다고 생각합니다.
class A
{
public:
virtual bool Check() { return false; };
}
class B : public A
{
public:
// override A::Check()
virtual bool Check() { return true; };
}
기본 클래스 A의 방법은 객체가 "실제로"A 또는 A B인지 여부를 알 필요가 없어야합니다. 기본 객체 지향 설계 원칙을 위반하는 것입니다. 객체가 B 인 경우 동작이 변경되어야하는 경우 해당 동작은 B로 정의되고 가상 메소드 호출에 의해 처리되어야합니다.
다른 팁
다만 움직임의 정의는 체크인()몸의:
#include <iostream>
#include <typeinfo>
using namespace std;
class B;
class A {
public:
int i_;
void Check ();
};
class B : public A {
public:
double d_;
};
void A::Check () {
if (typeid (*this) == typeid (B))
cout << "True: Same type as B." << endl;
else
cout << "False: Not the same type as B." << endl;
}
int main () {
A a;
B b;
a.Check (); // should be false
b.Check (); // should be true
return 0;
}
한 가지 방법은 정의를 가져 오는 것입니다 Check
클래스 정의에서 B
컴파일러가 함수 정의에 도달 할 때 정의됩니다.
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
클래스 B 선언 아래에 검사의 정의를 이동하십시오.
B의 선언 후 기능 본문을 이동하십시오.
#include <iostream>
#include <typeinfo>
struct A
{
int i_;
void Check();
};
struct B : A
{
double d_;
};
void A::Check()
{
using namespace std;
if (typeid (*this) == typeid (B))
{
cout << "True: Same type as B." << endl;
}
else
{
cout << "False: Not the same type as B." << endl;
}
}
int main()
{
A a;
B b;
a.Check(); // should be false
b.Check(); // should be true
return 0;
}
안녕하세요, A :: 클래스 밖에서 확인하는 경우에도 결과는 기대하는 것이 아닙니다. 이는 B 객체가 메소드의 A 객체로 변환하기 때문에 A 객체를 가리키므로 typeids는 항상 다릅니다. 이를 해결하려면 메소드 가상을 선언합니다.
그러나 나는 왜 당신이 왜 그런 테스트 O_O를 수행하고 싶은지 이해하지 못합니다. 그리고 Cadaker가 말했듯이 이것은 좋은 관행이 아닙니다
제휴하지 않습니다 StackOverflow