c++ - 如果要调用多个成员函数,对象编辑器是一个好方法吗?

标签 c++ templates c++14

我经常对这样的类成员函数的顺序调用感到恼火(忽略新用法,它是针对 Qt 的,但它与 Qt 并不严格相关)

A a = new A();
a->fun1("one");
a->fun2(1, 2);
...
a->fun10("end");

我总觉得这样的代码应该写成简单的指令,而不是项目主线。

Qt 的简单示例:

auto* spinBox = new QSpinBox();
spinBox->setRange(-100, 100);
spinBox->setValue(50);
spinBox->setSingleStep(5);
newLayout->addWidget(spinBox);

但我更愿意用简单的单行来完成此操作,而不是那样。所以我写了这样的东西:

class {
public:
    template<class X>
    auto& operator()(X* ptr) {
        this->ptr = ptr;
        return *this;
    }

    template<class X, class R, class... Args>
    auto& operator()(R (X::* fun)(Args...), Args... args) {
        if(ptr == nullptr) {
            std::cerr << "Editor can't edit nullptr" << std::endl;
            return *this;
        }
        auto call = std::mem_fn(fun);
        call(*static_cast<X*>(ptr), args...);
        return *this;
    }

    template <class X>
    operator X*() {
        auto* result = static_cast<X*>(ptr);
        ptr = nullptr;
        return result;
    }
private:
    void *ptr = nullptr;
} EDITOR;

现在的用法:

newLayout->addWidget(EDITOR(new QSpinBox)(&QSpinBox::setRange,-100, 100)(&QSpinBox::setValue, 50)(&QSpinBox::setSingleStep, 5));

除了不是类型安全之外,这是个好方法吗? (我可以忍受)

--- 编辑 ---

另一种类型安全的方法是:

template<class X>
class EDITOR2 {
public:
    EDITOR2(X* ptr) {
        this->ptr = ptr;
    }

    template<class R, class... Args>
    auto& operator()(R (X::* fun)(Args...), Args&&... args) {
        if(ptr == nullptr) {
            std::cerr << "Editor can't edit nullptr";
            return *this;
        }
        auto call = std::mem_fn(fun);
        call(*ptr, args...);
        return *this;
    }

    operator X*() {
        return ptr;
    }

    X *ptr;
};

使用情况:

newLayout->addWidget(EDITOR2<QSpinBox>(new QSpinBox)(&QSpinBox::setRange, -100, 100)(&QSpinBox::setValue, 50)(&QSpinBox::setSingleStep, 5));

但这需要每次重新创建编辑器对象,并添加额外的使用代码。

最佳答案

我们来战斗吧

第一个对手,普通方法:

auto* spinBox = new QSpinBox();
spinBox->setRange(-100, 100);
spinBox->setValue(50);
spinBox->setSingleStep(5);
newLayout->addWidget(spinBox);
  • 优点:

    • 所有人都是这样做的
    • 大约 30 列宽,非常易读
  • 缺点:

    • 需要 5 行
    • spinBox 操作的主题每次都会重复

第二个对手,奇特的方法:

newLayout->addWidget(EDITOR2<QSpinBox>(new QSpinBox)(&QSpinBox::setRange, -100, 100)(&QSpinBox::setValue, 50)(&QSpinBox::setSingleStep, 5));
  • 优点:

    • 只需一行
    • 这在某种程度上是一种更实用的编程方法
  • 缺点:

    • 这是一个很长的行,很难阅读
    • 默认情况下,人们的 react 会是 wtf 的变体,因为他们不习惯
    • 实例名称 spinBox 不再重复,但类名称 QSpinBox 现在是

最终的选择取决于你对每个点的重视程度,我确实在一行中比较了第二种方法,就好像你使用换行符一样,你基本上回到了你试图修复的原始问题

以我的拙见,添加这么少的类开销是不值得的,而且我是那种对原始方法的缺点感到恼火的人,致命点是可读性损失,这很可能会迫使你使用换行符意味着你所做的这一切都是徒劳的。

关于c++ - 如果要调用多个成员函数,对象编辑器是一个好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42140222/

相关文章:

c++ - 对 std::hash<string> 的 undefined reference

c# - 毛玻璃窗上的非客户绘画

c++ - 模板类中的通用模板指针

c++ - 是否可以简单地复制::std::tuple-like 类模板?是否存在实现?

c++ - 在 C++14 中,可恢复函数将在什么情况下执行?

c++ - GDI+ 对象的 std::make_unique

C++ 'this' 和运算符重载

c++ - 重新排序 C++ 模板函数

javascript - 如何从 Webix 组合中选定的数据项获取属性?

c++ - 将 "pointer to pointer"传递给模板函数