- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题非常具体。我有以下要求,出于多种原因,我需要从父类设置存在于子类中的成员变量。我的计划是在构造时将以字符串为参数的setter方法(存在于子类中)的函数指针传递给父类。父类定义了一个公共(public)方法,该方法以成员名称和值字符串为参数,并调用具有值字符串的成员的函数指针。父类可以存在于 dll 或 lib 中,并且无法访问任何转换或工厂方法,因此必须在子类中定义 setter 方法。
由于父类可以作为其他类的基类,我写了一些如下所示的宏:
#define DEFINE_VAL(Type, memberName) \
private: \
Type memberName; \
void set##memberName(std::string const& val) { \
memberName = convert_to_val(val); /* this will be a call to factory which converts string to value type*/\
/* or call to local implementation for conversion*/
}; \
#define INIT_VAL(memberName) \
{ memberName, \
[&](std::string const& val) { set##memberName(val); }}
父子类如下:
// parent.h probably in dll
class parent
{
public:
parent(std::map<std::string, std::function<void(std::string const&)>>& m)
: m(m)
{ }
...
private:
std::map<std::string, std::function<void(std::string const&)>> m;
};
// child.h
class child : public parent
{
public:
child() : parent({ INIT_VAL(iVal), ... })
{ }
private:
DEFINE_VAL(int, iVal);
...
};
子类可以定义很多变量,首先使用 DEFINE_VAL 宏,然后使用 INIT_VAL 宏传递每个变量的 setter 方法有点烦人。这可以在一个宏中完成吗(可能在 DEFINE_VAL 中)?或者关于自动注册成员名称和函数指针到父类的任何想法?
我也很感激任何关于完成我的要求的替代想法。
最佳答案
I need to set member variables that exist in child class from parent class, for several reasons. My plan is to pass a function pointer of the setter method (which exist in child class), that takes string as argument, to the parent class at construction.
当父类构造函数被调用时,派生类及其成员还没有被初始化,并且迂腐地说,它们还不存在。因此,不可能从其基类构造函数设置派生类成员。
一种解决方案是使用虚函数按名称设置成员。
在当前的 C++ 中没有内置反射,要将名称与数据成员相关联并生成成员访问器,最佳实践仍然是使用宏。为此目的最好的宏之一是 BOOST_HANA_DEFINE_STRUCT
.
boost::lexical_cast<T>
可用于从 std::string
转换到任何 T
.
具有深度和多重继承支持的工作示例:
#include <boost/hana/define_struct.hpp>
#include <boost/hana/accessors.hpp>
#include <boost/hana/for_each.hpp>
#include <boost/hana/concat.hpp>
#include <boost/hana/length.hpp>
#include <boost/lexical_cast.hpp>
#include <unordered_map>
#include <functional>
#include <iostream>
namespace hana = boost::hana;
struct MemberSetter {
// Using void* to reduce the number of template instantiations.
using SetterFn = std::function<void(void*, std::string const&)>;
using Setters = std::unordered_map<std::string, SetterFn>;
Setters setters_;
template<class Derived, class Accessors>
MemberSetter(Derived* that, Accessors& accessors) {
hana::for_each(accessors, [this](auto const& pair) {
auto setter = [accessor = hana::second(pair)](void* vthat, std::string const& value) {
auto* that = static_cast<Derived*>(vthat);
auto& member = accessor(*that);
member = boost::lexical_cast<std::remove_reference_t<decltype(member)>>(value);
};
auto name = hana::first(pair);
setters_.emplace(std::string(hana::to<char const*>(name), hana::length(name)), std::move(setter));
});
}
bool findAndSetMember(void* that, std::string const& name, std::string const& value) const {
auto setter = setters_.find(name);
if(setter != setters_.end()) {
(setter->second)(that, value);
return true;
}
return false;
}
};
struct A {
virtual ~A() = default;
virtual bool setMember(std::string const& name, std::string const& value) = 0;
};
struct B : A {
BOOST_HANA_DEFINE_STRUCT(B,
(int, a),
(double, b)
);
bool setMember(std::string const& name, std::string const& value) override {
constexpr auto accessors = hana::accessors<B>();
static MemberSetter const setter(this, accessors);
return setter.findAndSetMember(this, name, value);
}
};
struct C : B {
BOOST_HANA_DEFINE_STRUCT(C,
(std::string, c)
);
bool setMember(std::string const& name, std::string const& value) override {
constexpr auto accessors = hana::concat(hana::accessors<B>(), hana::accessors<C>()); // Join with members of the base class.
static MemberSetter const setter(this, accessors);
return setter.findAndSetMember(this, name, value);
}
};
int main() {
C c;
c.setMember("a", "1");
c.setMember("b", "2.3");
c.setMember("c", "hello");
std::cout << c.a << ' ' << c.b << ' ' << c.c << '\n';
}
输出:
1 2.3 hello
关于c++ - 关于摆脱样板代码的想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56732377/
所以这个有点难以解释,但我会尝试一下: 我有一个带有 .boxes 类的 div。它是一些循环元素的包装。循环元素具有类.box。在这个元素中,还有两个元素。一种是 .box-header 类的 he
我有一个网站,我试图在调整浏览器窗口大小时使其表现得体。例如,我希望在有人缩小浏览器窗口时调整横幅图像的大小。网址是http://www.pfp-consortium.org 顶部的横幅在 CSS 中
我想知道情况,是将所有可能的元素都放在表单中更好,还是在用户需要时立即将元素添加到表单中更好。 我将尝试对其进行更多解释 - 我的表单具有 4 个输入和一个文本区域。然后我提供了可选值(大约 15 -
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
所以我一直在研究我正在构建的一个论坛,并且一直专注于它的一个方面,即如何在不在数据库中存储大量数据的情况下跟踪未读的帖子和通知。在查看了一些解决方案之后,我相信我想出了一个可能适合我需要的解决方案,但
编写一个高质量的软件应该是第一步。现在这是一个移动的目标。(我们有一些类似于 https://stackoverflow.com/questions/3716203/automatic-code-qu
我有一组存储在数组中的二维点。 我需要尽可能多地压缩它。最好是快速,但不要破坏交易,压缩率是目标。规则是: 一个点=一个32位的结构,存储为(x,y),每个坐标2个字节 坐标 = 8 位整数部分和 8
我的一个应用程序从服务器下载数据库。当我将应用程序安装到我的手机上时,它会正确下载文件并加载信息,没有抛出任何异常或任何东西。 但是,当我将 apk 上传到 Android Market Place
我们最近接到一位客户的电话,提示他们网站的页面底部有一些“看起来很奇怪的代码”。我们查看了源代码,发现 templates/master 中附加了大约 800 字节的恶意 javascript 代码。
以编程方式创建系统还原点是“禁忌”吗?我会在执行软件更新之前执行此操作。如果有更好的方法可以仅使用我的软件文件和数据创建还原点,请告诉我。 我想要一种方法,如果在更新期间一切都发生了故障(关闭/终止更
我有一个有很多相关模型的类问题。在我的应用程序的一个页面上,我列出了所有当前问题的摘要,以及来自相关记录的各种信息。最终,这是一个值的散列,然后我将其打印到一个 csv 样式的行中(从这里我将其称为“
我目前正在尝试从 NSClassFromString(NSString *) 方法创建对象。 我希望能够实现的是以下... NSClassFromString(stringType) *pageCon
使用 Intellij 想法,我如何找出使变量可见的原因? 困难时的示例: 假设你看 class A ,你会看到一个变量 something .如果你跳转到源代码,你会看到它是在 trait X 中定
在IntelliJ IDEA的代码样式设置中,没有.gradle文件的任何子类别(例如build.gradle),在“其他文件类型”下,没有任何选项可以修改花括号位置。我没有找到为.gradle文件设
我正在尝试按照here指令运行docker-compose,但它似乎陷入了循环。在安装Docker之前,我能够调出示例站点并进行一些外观上的更改,但是尝试使用docker-compose生成缩略图23
我正在使用 IntelliJ IDEA 12.1.4 来调试 Grails 应用程序。我开始调试 session 大约需要 2 分钟。我想尽可能避免重新启动。 我正在尝试调试一个 Controller
随着 .NET 4.0 的出现,MS AJAX 是否仍占有一席之地,或者您认为 JQuery 是否会扩展以包含 AJAX 的全部功能,并使我们所知的 MS AJAX 变得多余? 最佳答案 请记住,AS
需要帮助运行此示例 Google+ API Quickstart w/C# 应用程序,请使用 VS2015 并按照此处的说明操作:https://developers.google.com/+/web
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我有一个相当“疯狂”的想法,即在我的应用程序中拥有一个“存储过程”设施。基本上,我的应用程序以数据为中心,它可以通过某种形式的 Restful 界面访问数据存储。 我希望拥有以多种方式操作数据(这是一
我是一名优秀的程序员,十分优秀!