Base class with pointer to derived object: 如何判断彼此的存在?
Base class with pointer to deriving object: How to tell both of each other's existence?
这是一个最小的例子。我有一个 Base class 需要知道 Deriving class。反过来,Deriving class 需要知道 Base class。那么如何定义它们,让它们知道彼此的存在呢?
class Base {
Deriving* d;
public:
Base(Deriving* deriving) {
d = deriving;
}
void f() {
d->g();
}
};
class Deriving : public Base {
public:
Deriving() : Base(this) {}
g();
};
这是我尝试过的和编译器说的:
定义 Base
首先导致 error: 'Deriving' does not name a type
。定义 Deriving
首先导致 error: expected class-name before '{' token
。声明 Base
或 Deriving
的不完整类型会导致 error: invalid use of incomplete type 'class X'
。我不知道还能尝试什么。
非常感谢任何帮助。
在Base中,只有函数f
需要知道class的定义Deriving
,所以在定义Deriving
之后定义它。
class Deriving;
class Base {
Deriving* d;
public:
Base(Deriving* deriving) {
d = deriving;
}
void f();
};
class Deriving : public Base {
public:
Deriving() : Base(this) {}
void g();
};
void Base::f()
{
d->g();
}
这种排列一般是逻辑错误。基 class 永远不需要知道派生 class 的任何信息。如果基 class 中的方法需要使用恰好存储在派生 class 中的资产,则可以将对这些资产的引用传递到函数 f()。
在上面的示例中,可以通过继承实现所需的行为:
像这样:
class Base
{
public:
void f() {
impl_f();
}
private:
virtual void impl_f() = 0;
};
class Derived : public Base
{
private:
void impl_f() override
{
// whatever g() was going to do...
}
};
这是一个最小的例子。我有一个 Base class 需要知道 Deriving class。反过来,Deriving class 需要知道 Base class。那么如何定义它们,让它们知道彼此的存在呢?
class Base {
Deriving* d;
public:
Base(Deriving* deriving) {
d = deriving;
}
void f() {
d->g();
}
};
class Deriving : public Base {
public:
Deriving() : Base(this) {}
g();
};
这是我尝试过的和编译器说的:
定义 Base
首先导致 error: 'Deriving' does not name a type
。定义 Deriving
首先导致 error: expected class-name before '{' token
。声明 Base
或 Deriving
的不完整类型会导致 error: invalid use of incomplete type 'class X'
。我不知道还能尝试什么。
非常感谢任何帮助。
在Base中,只有函数f
需要知道class的定义Deriving
,所以在定义Deriving
之后定义它。
class Deriving;
class Base {
Deriving* d;
public:
Base(Deriving* deriving) {
d = deriving;
}
void f();
};
class Deriving : public Base {
public:
Deriving() : Base(this) {}
void g();
};
void Base::f()
{
d->g();
}
这种排列一般是逻辑错误。基 class 永远不需要知道派生 class 的任何信息。如果基 class 中的方法需要使用恰好存储在派生 class 中的资产,则可以将对这些资产的引用传递到函数 f()。
在上面的示例中,可以通过继承实现所需的行为:
像这样:
class Base
{
public:
void f() {
impl_f();
}
private:
virtual void impl_f() = 0;
};
class Derived : public Base
{
private:
void impl_f() override
{
// whatever g() was going to do...
}
};