如何使用派生类中的虚拟函数,该函数在另一个具有基类参数的类中声明
How to use a virtual function from derived class, declared in another class with base class parameters?
问题是我想列出一个名为Resource的类中的元素;在另一个类中,我有一个函数:void KeyDistributionCenter::ListResources()
,我想从派生类File或类Server调用一个名为PRINT的函数。类服务器和文件是从资源派生的。我之所以要这样做,是因为在我的派生类中,我修改了一个PRINT函数。(例如,在文件中我打印输出文件,而在服务器中只是一般的东西)。
在KeyDistributionCenter中,我有一个资源列表(而不是派生文件或服务器的列表)。那么,我如何知道要调用哪个print(什么派生类来自参考资料),以及如何做到这一点呢?谢谢
编辑:我从参考资料中打印的函数是虚拟void print();我在想,如果我这样声明,它就会知道从File或Server访问print()函数。
编辑2:更准确地说:我的KeyDistributionCenter中有另一个函数RegisterResource(Resource&R),它将资源添加到我的std::vector资源中(vector也来自KDC);假设我有一个资源文件,我只想从KeyDistributionCenter调用Print()函数(带我的资源向量列表)来知道资源是什么类型的,并从File或Server类调用Print(
class Resource
{
public:
virtual ~Resource() { }
virtual void print() = 0;
};
class Server : public Resource
{
public:
void print() override { std::cout << "server" << std::endl; }
};
class File : public Resource
{
public:
void print() override { std::cout << "file" << std::endl; }
};
您只需要确保Resource
类在其接口中提供了virtualprint
函数(在上面的示例中,它是纯虚拟的,但这不是强制性的)。
现在你可以拥有:
std::unique_ptr<Resource> r = new Server();
r->print();
r = new File();
r->print();
重要信息:您需要通过指针或引用来引用对象。如果你不这样做,那么你会遇到一种叫做"对象切片"的现象:
Resource r = Server(); // server part in r will be sliced away and a pure
// Resource object remains!!!
如果你有Resource
类型的STL容器:,这种情况也会发生
std::vector<Resource> resources;
(但是,如果您的类是抽象的,即包含纯虚拟函数,则根本无法做到这一点&准确地说:您可以创建向量,但不能将元素放入其中)。
编辑:如注释所示,对象切片是实现中实际发生的事情。你需要重新设计。一种变体可能看起来像这样:
std::vector<std::unique_ptr<Resource>> resources;
void registerResource(std::unique_ptr<Resource> r)
{
resources.emplace_back(std::move(r));
}
registerResource(std::make_unique<Server>());
registerResource(std::make_unique<File>());
这个场景将资源的所有权转移到向量,它可能会满足您的需求。还有许多其他可能的变体,但无论你做什么,你都需要指针(智能与否)或向量中的引用。
您为所有资源调用相同的print()方法。这就是多态性的意义——以相同的方式处理相同类型的对象。一个虚拟表是代表您在后台实现的,它知道实际调用哪个print()方法。下面的代码应该清楚:
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Resource
{
public:
explicit Resource() { }
virtual ~Resource() { }
virtual void Print() = 0;
};
class File : public Resource
{
public:
explicit File() : Resource() { }
virtual ~File() { }
void Print() override { cout << "Print called from File class" << endl; }
};
class Server : public Resource
{
public:
explicit Server() : Resource() { }
virtual ~Server() { }
void Print() override { cout << "Print called from Server class" << endl; }
};
class KeyDistributionCenter
{
public:
explicit KeyDistributionCenter()
{
resources.emplace_back(make_unique<File>());
resources.emplace_back(make_unique<Server>());
}
void ListResources()
{
for (const auto& resource : resources)
resource->Print();
}
private:
vector<unique_ptr<Resource>> resources;
};
int main()
{
unique_ptr<KeyDistributionCenter> hub = make_unique<KeyDistributionCenter>();
hub->ListResources();
getchar();
}
- Visual Studio中的函数声明和函数定义问题
- 为什么函数声明中允许 const?
- 如果 x.h 仅由函数声明组成,为什么有必要在 x 中包含 x.h.cpp
- * 和 ** 在 C++ 函数声明中是什么意思?
- 构造函数/函数声明参数列表中的统一初始化
- 在将函数声明为友元时,尖括号的含义是什么?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 如何正确编写指针函数声明?
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 为什么要将函数声明和定义放在单独的文件中
- 为什么系统日志有两个不同的函数声明?
- 我如何获取数组的大小,以便我可以从函数声明所述数组
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- JavaScript 中的一等函数和 C++ 中的函数声明
- C++ 通过函数声明后初始化向量
- VS2017 #error: : snprintf 的宏定义与标准库函数声明冲突
- C++ 17 个友元函数声明和内联命名空间
- MSVC 2017 - 错误 - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的好友
- 将派生类的构造函数声明为父类的友元
- 用于从 ANSI 字符串转换为 std::basic_string <TCHAR>的正确函数声明