C++私有和受保护的虚拟方法
C++ private and protected virtual method
似乎最好将虚拟方法设为私有,以便分离以下两个客户端的接口 -1. 实例化对象并调用该方法的客户端2. 派生自类并可能想要重写该方法的客户端。简单地说 - 第一个客户端不需要知道方法是否是虚拟的。他将基类称为公共非虚拟方法,而基类又将调用私有虚拟方法。例如,请参阅下面的代码。
现在,在虚拟方法需要对其基类的相应虚拟方法(例如 Save 方法)发送超级消息的情况下 - 它必须通过继承链中的所有虚拟方法才能保存对应于每个派生级别的数据 - 我们别无选择,只能使用受保护的虚拟方法 - 除非有一种方法可以保证在所有派生级别保存数据而不使用超级消息(我不知道)。
我想知道上述推理是否正确。
确保使用滚动来查看整个代码。
#include <iostream>
using namespace std;
class A {
string data;
protected:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
protected:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
class C : public B {
string data;
protected:
virtual void SaveData() {
B::SaveData();
cout << data << endl;
}
public:
C():data("Data of C") {}
};
int main(int argc, const char * argv[])
{
C c;
c.Save();
return 0;
}
是的,如果您需要调用另一个类的 SaveData,则需要从该类访问它 - 所以public
或protected
。
你说得对:
- NVI(非虚拟接口)要求不
virtual
方法public
- 调用基类方法要求它不能
private
因此,protected
是显而易见的解决方案,至少在 C++03 年是这样。不幸的是,这意味着您必须信任派生类开发人员,不要忘记调用"super"。
在 C++11 中,您可以使用 final
来防止派生类重写 virtual
方法;这意味着您被迫引入一个新的钩子,例如:
class Base {
public:
void save() {
// do something
this->saveImpl();
// do something
}
private:
virtual void saveImpl() {}
};
class Child: public Base {
private:
virtual void saveImpl() final {
// do something
this->saveImpl2();
// do something
}
virtual void saveImpl2() {}
};
当然,每次都必须想出一个新名字的麻烦......但至少可以保证Child::saveImpl
会被调用,因为它的子项都无法覆盖它。
很难说出你在问什么,但从示例中,你不需要保护该方法。 它实际上可以是私有的。 有关微妙之处的详细信息,请参阅这篇文章:私有纯虚拟函数的意义何在?
只要您不从派生类(或外部类)调用私有成员,就可以了。 覆盖私有成员是可以的。 你可以覆盖父母的隐私,这听起来确实很顽皮和错误,但在 c++ 中,你可以这样做。
以下应该没问题:
#include <iostream>
using namespace std;
class A {
string data;
private:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
private:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 使用模板而不是虚拟方法的管道模式
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 为什么调用没有正文的纯虚拟方法不会导致链接器错误?
- 出于什么目的,非虚拟方法将与C++一起使用?
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 如何重写继承的嵌套类中存在的虚拟方法
- 私有虚拟方法有什么用?
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- googletest:测试基类具有纯虚拟方法的派生类时的核心转储
- 确保模拟的 GTest 方法覆盖虚拟方法
- CPP 继承虚拟方法解析顺序
- 我是否应该在包含虚拟方法的类上使用'memcpy'?如果没有,如何替换它?
- 用c++中的纯虚拟方法抽象模板类
- 解决虚拟方法的歧义继承的两种方法
- 没有针对完全专用模板类的外联虚拟方法定义