【问题标题】:Class method to call variable method类方法调用变量方法
【发布时间】:2023-03-19 11:20:02
【问题描述】:

我目前的情况是这样的结构:

class Foo {
    public:
        void call() {
            b.call();
        }
    private:
        Bar b;
};

class Bar {
    public:
        void call() {
            std::cout << "Hello there" << std::endl;
        }
};

int main() {
    Foo f;

    f.call(); // This calls directly the b.call() function
}

有没有一种语法可以直接让Foo.call函数直接调用类内存储为变量的函数?

基本上,有没有一种语法可以做这样的事情:

class Foo {
    public:
        void call() -> b.call
    private:
        Bar b;
};

【问题讨论】:

  • 不。你所拥有的是你需要做的方式(忽略Bar需要在Foo之前定义它才能实际编译)
  • b private 不是有原因的吗?
  • @CinCout 有选择地桥接到b 上的某些方法是一种相当常见的模式。
  • 无关:据我所知Bar b; 从未做过劳伦b.call(); 娃娃。

标签: c++ class syntax simplify


【解决方案1】:

您说的是语言级别的 delegate 构造。某些语言对此具有内置支持,但 C++ 没有。你必须像你一样“艰难地”去做。

如果这是一个非常普遍的事情,你可以定义一个宏,但通常最好有丑陋的代码而不是混乱或误导性的代码。

【讨论】:

  • 我太懒了,想知道它是否已经存在,但我想我会继续正确编码......
  • 那种懒惰绝对没有错。就你所知,C++17 正好加入了这个特性。
  • 你做的方式。
  • class Foo { public: void call() -> b.call private: Bar b; };等等,这行得通吗?
  • 不,我的意思是你这样做的长篇形式。区别是零个字符,{} vs. -&gt;,所以我不知道这里大惊小怪。
【解决方案2】:

通常没有必要像这样尝试帮助编译器。编译器非常擅长优化这类事情。你不需要告诉编译器Foo::call 真的只是一个Bar::call。编译器会弄清楚的。考虑一个稍微调整的例子:

extern void DisplayMessage(char const*);

class Bar {
public:
  void call() {
    DisplayMessage("Hello there");
  }
};

class Foo {
public:
  void call() {
    b.call();
  }
private:
  Bar b;
};

int main() {
  Foo f;

  f.call(); // This calls directly the b.call() function
}

当我使用 Clang 7.0 和 -O3 编译它时,我得到以下信息:

main:                                   # @main
    push    rax
    mov     edi, offset .L.str
    call    DisplayMessage(char const*)
    xor     eax, eax
    pop     rcx
    ret

请注意,编译器已完全删除对象,只留下对DisplayMessage 函数的直接调用。

【讨论】:

  • 我实际上并没有看到 OP 的问题是关于优化的,而是 根据定义 Foo::call 公开了(否则为私有的)Foo::b.call。这种语义的语言构造并不是一件不合理的事情。 (碰巧它当然不存在)。
  • 是的。鉴于他接受了这些方面的答案,看来我误解了。 ;)
【解决方案3】:

你可能有更短的代码:

class Bar {
public:
    void call() const {
        std::cout << "Hello there" << std::endl;
    }
};

class Foo : private Bar // private is superfluous here, as we use class instead of struct
{
public:
    using Bar::call;
};

但手动转发的组合方式似乎更自然。

【讨论】:

    猜你喜欢
    • 2011-04-20
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多