有没有办法防止在派生 class 中调用特定的继承函数?
Is there a way to prevent calls to a specific inherited function in a derived class?
考虑以下几点:
class base {
// base class
public:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class derived : public base {
// this class inherits 'doBaseStuff()' as well as 'someDataMember'
public:
void doDerivedStuff() {
/* do something in addition that only this type of derived class can do */
}
};
class specialDerived : public base {
// say 'doBaseStuff()' doesn't make sense in the context of this class!
// we do not want to inherit that function here
// is there a way to prevent instances of this class from calling it?
// we still want 'someDataMember', so we must derive from the base class
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
有一个 class 作为多个其他 class 的共同基础 class。但是,让我们假设它在派生的 classes 之一中不需要的基本 class' 成员函数之一。有没有办法在派生的 class?
中明确禁止继承函数
实际上我们可以谈论一个有 1000 个成员的基 class,而我们想要继承其中的 999 个,因此简单地放弃继承并复制所有代码将导致代码可维护性非常差.
在基础 class 中使该函数成为虚拟函数,并在 specialDerived
class 中提供它的虚拟实现是可行的。但是,如果该函数具有实际的 return 类型,而不是 void
怎么办?然后 specialDerived
class 必须提供一个 return 的实现。调用者然后可以假设他们得到的值是有意义的,但实际上不是,这就是一个问题。
简单地在 specialDerived
中实现虚函数并在主体中使用单个 throw
可能是一个解决方案,只要存在一些文档明确说明在这个特定的对象上调用此函数派生类型没有任何意义,并且该操作将抛出。我认为这是一种可能的解决方案,但我不确定这是否是最好的方法。
我假设您只是想确保该方法不会被意外调用,即调用时出现编译错误是完美的。
您可以简单地用删除的定义覆盖 specialDerived
中的 doBaseStuff
:
class specialDerived : public base {
void doBaseStuff() = delete;
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
这将阻止任何人使用 specialDerived::doBaseStuff
。仍然可以将对 specialDerived
的引用转换为对 base
的引用并在结果上调用 doBaseStuff
,但是如果不使 doBaseStuff
virtual
.
- 声明
doBaseStuff
在 base
中受保护
- 从
base
中派生出一个新的 class base2
,这使得 doBaseStuff
public
- 从
base2
而不是 base
导出 999 classes
- 从
base
推导出 class
像这样:
class base {
protected:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class base2 : public base {
public:
using base::doBaseStuff; // make it public
};
class derived : public base2 {
// ...
};
class specialDerived : public base {
// doBaseStuff not public here since we're derived only from base (and not base2) and didn't make it public ourself
};
考虑以下几点:
class base {
// base class
public:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class derived : public base {
// this class inherits 'doBaseStuff()' as well as 'someDataMember'
public:
void doDerivedStuff() {
/* do something in addition that only this type of derived class can do */
}
};
class specialDerived : public base {
// say 'doBaseStuff()' doesn't make sense in the context of this class!
// we do not want to inherit that function here
// is there a way to prevent instances of this class from calling it?
// we still want 'someDataMember', so we must derive from the base class
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
有一个 class 作为多个其他 class 的共同基础 class。但是,让我们假设它在派生的 classes 之一中不需要的基本 class' 成员函数之一。有没有办法在派生的 class?
中明确禁止继承函数实际上我们可以谈论一个有 1000 个成员的基 class,而我们想要继承其中的 999 个,因此简单地放弃继承并复制所有代码将导致代码可维护性非常差.
在基础 class 中使该函数成为虚拟函数,并在 specialDerived
class 中提供它的虚拟实现是可行的。但是,如果该函数具有实际的 return 类型,而不是 void
怎么办?然后 specialDerived
class 必须提供一个 return 的实现。调用者然后可以假设他们得到的值是有意义的,但实际上不是,这就是一个问题。
简单地在 specialDerived
中实现虚函数并在主体中使用单个 throw
可能是一个解决方案,只要存在一些文档明确说明在这个特定的对象上调用此函数派生类型没有任何意义,并且该操作将抛出。我认为这是一种可能的解决方案,但我不确定这是否是最好的方法。
我假设您只是想确保该方法不会被意外调用,即调用时出现编译错误是完美的。
您可以简单地用删除的定义覆盖 specialDerived
中的 doBaseStuff
:
class specialDerived : public base {
void doBaseStuff() = delete;
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
这将阻止任何人使用 specialDerived::doBaseStuff
。仍然可以将对 specialDerived
的引用转换为对 base
的引用并在结果上调用 doBaseStuff
,但是如果不使 doBaseStuff
virtual
.
- 声明
doBaseStuff
在base
中受保护
- 从
base
中派生出一个新的 classbase2
,这使得doBaseStuff
public - 从
base2
而不是base
导出 999 classes
- 从
base
推导出 class
像这样:
class base {
protected:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class base2 : public base {
public:
using base::doBaseStuff; // make it public
};
class derived : public base2 {
// ...
};
class specialDerived : public base {
// doBaseStuff not public here since we're derived only from base (and not base2) and didn't make it public ourself
};