error C2039,不是类成员 问题出现的原因之一与解决方法
在visual stdio中编代码时,编译器有时会给代码报出 不是类成员 的错误,错误为error C2039。
场景:例如观察者模式中,两个类相互需要以对方做为自己函数的参数或本身包含对方类的指针,也需要在自己类的方法定义中调用另一个类的函数
报错原因:使用了未被声明 的类或函数,即类和函数被调用前必须声明。不然报错error C2039,不是类成员
正确步骤:
1.写出两个类的声明
2.写出两个类中成员与函数的声明(此时已经被声明的类就可以作为指针参数了)
3.写出类外依次定义函数成员(此时被声明的函数就可以作为其他类定义函数时的调用对象了)
代码示范
//第一步先声明类存在,使得该类对象或指针可以作为参数
class A;
class B;
//第二步声明类中成员,使得该类中的成员与函数可以被调用而不报错
class A
{
public:
//在观察对象B中注册自己
void RegisterB(B* Target);//B类因为已经被声明过,因此此处可以作为指针参数传入
//应对观察对象的消息作出反应
void Action();
//观察对象B
B* mTarget;//B类因为已经被声明过,因此此处可以有指针存在
};
class B
{
public:
//向观察者发送消息
void Notify();
//添加自己的观察者
void GetWatcher(A* Watcher);
//观察者A
A* mWatcher;
};
//第三步定义类中成员,要在被使用的函数都已经被声明的条件下,
//才能使定义中调用函数而不报错,否则调用违背声明的函数时,
//会出现 error C2039,不是类成员 问题
void A::RegisterB(B* Target)
{
//向观察对象B注册自己
Target->GetWatcher(this);
}
void A::Action()
{
//干了些事情
cout << "我收到了通知并干了点活" << endl;
}
void B::Notify()
{
//通知观察者办事
mWatcher->Action();
}
void B::GetWatcher(A* _Watcher)
{
//获取到观察者指针
mWatcher = _Watcher;
}
void test()
{
A* Watcher = new A;
B* Target = new B;
Watcher->RegisterB(Target);
Target->Notify();
delete Watcher;
delete Target;
}
int main()
{
test();
}
在比较大的工程中遇到需要用到观察者模式这种,在两个或两个以上的类中成员函数相互调用,类作为相互函数参数时,就有必要在一个头文件中做好所有相关类的声明,相关类中函数的声明,剩下所有相关类的定义实现则可以用其他cpp文件包含这个头文件来分别实现。