问题描述
我正在尝试实现自定义 vtable 以更好地理解虚拟表和覆盖的概念。为此,我有以下“基础”类
#pragma once
#include <iostream>
#include <string>
using namespace std::string_view_literals;
struct vtable;
class IdentityDocument {
public:
IdentityDocument()
: vtable_ptr_(&IdentityDocument::VTABLE),unique_id_(++unique_id_count_)
{
std::cout << "IdentityDocument::Ctor() : "sv << unique_id_ << std::endl;
}
~IdentityDocument() {
--unique_id_count_;
std::cout << "IdentityDocument::Dtor() : "sv << unique_id_ << std::endl;
}
IdentityDocument(const IdentityDocument& other)
: vtable_ptr_(other.vtable_ptr_),unique_id_(++unique_id_count_)
{
std::cout << "IdentityDocument::CCtor() : "sv << unique_id_ << std::endl;
}
IdentityDocument& operator=(const IdentityDocument&) = delete;
void PrintID() const {
std::cout << "IdentityDocument::PrintID() : "sv << unique_id_ << std::endl;
}
static void PrintUniqueIDCount() {
std::cout << "unique_id_count_ : "sv << unique_id_count_ << std::endl;
}
int GetID() const {
return unique_id_;
}
private:
vtable* vtable_ptr_ = nullptr;
static int unique_id_count_;
static vtable VTABLE;
int unique_id_;
};
struct vtable
{
void (IdentityDocument::* const PrintID)() const;
vtable (
void (IdentityDocument::* const PrintID)() const
) : PrintID(PrintID) {}
};
int IdentityDocument::unique_id_count_ = 0;
vtable IdentityDocument::VTABLE = {&IdentityDocument::PrintID};
这是另一个必须覆盖 PrintId
方法的类
#pragma once
#include "identity_document.h"
#include <iostream>
#include <string>
#include <ctime>
using namespace std::string_view_literals;
class Passport {
public:
Passport()
: expiration_date_(GetExpirationDate())
{
IdentityDocument* base_ptr = reinterpret_cast<IdentityDocument*>(this);
vtable* vtable_ptr = reinterpret_cast<vtable*>(base_ptr);
vtable_ptr = &Passport::VTABLE;
std::cout << "Passport::Ctor()"sv << std::endl;
}
Passport(const Passport& other)
: identity_(other.identity_),expiration_date_(other.expiration_date_)
{
IdentityDocument* base_ptr = reinterpret_cast<IdentityDocument*>(this);
vtable* vtable_ptr = reinterpret_cast<vtable*>(base_ptr);
vtable_ptr = &Passport::VTABLE;
std::cout << "Passport::CCtor()"sv << std::endl;
}
~Passport() {
std::cout << "Passport::Dtor()"sv << std::endl;
}
void PrintID() const {
std::cout << "Passport::PrintID() : "sv << identity_.GetID();
std::cout << " expiration date : "sv << expiration_date_.tm_mday << "/"sv << expiration_date_.tm_mon << "/"sv
<< expiration_date_.tm_year + 1900 << std::endl;
}
void PrintVisa(const std::string& country) const {
std::cout << "Passport::PrintVisa("sv << country << ") : "sv << identity_.GetID() << std::endl;
}
private:
IdentityDocument identity_;
const struct tm expiration_date_;
static vtable VTABLE;
tm GetExpirationDate() {
time_t t = time(nullptr);
tm exp_date = *localtime(&t);
exp_date.tm_year += 10;
mktime(&exp_date);
return exp_date;
}
};
vtable Passport::VTABLE = {reinterpret_cast<void (IdentityDocument::*)() const>(&Passport::PrintID)};
还有一个简短的演示:
int main() {
array<IdentityDocument*,1> docs = { (IdentityDocument*)(new Passport()) };
for (const auto* doc : docs) {
doc->PrintID();
}
}
不幸的是,我看到未调用“派生”方法。我是否使用了错误的方法来实现 vtable 概念?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)