【问题标题】:Dynamic binding to function depending on arguments in C++根据 C++ 中的参数动态绑定到函数
【发布时间】:2018-02-07 01:41:09
【问题描述】:

我希望赋值运算符根据参数类型动态绑定:

struct NumberObject;
struct NumberString;

struct DataType
{
    virtual void operator=(DataType& rhs) {};
    virtual void operator=(NumberString& rhs) {};
};
struct NumberObject : DataType
{
    double data = 7;
    void operator=(DataType& rhs)  override
    {
        std::cout << "Copying from DataType\n"; 
// The assignment operator that's called is this one. I was hoping it would be the one below.
    }
    void operator=(NumberString& rhs) override
    {
        std::cout << "Copying from NumberString\n";
    }
};
struct NumberString : DataType
{
    std::string data = "7";
    void operator=(NumberString& rhs) override{};
};


int main()
{
    DataType *pDataType1, *pDataType2;
    pDataType1 = new NumberObject;
    pDataType2 = new NumberString;
    *pDataType1 = *pDataType2;   // Both pointers are to DataType, I was hoping that the assignment operator taking 
                            // NumberString as the right hand side would be called


    return 0;
}

据此,我猜 C++ 不能根据参数类型动态绑定函数。动态绑定仅在直接通过对象调用函数时发生。所以我想我可以做到这一点,但这似乎是一种迂回的方式:

struct NumberObject : DataType
{
    double data = 7;
    void operator=(DataType& rhs)  override
    {
        std::cout << "Copying from DataType\n";
        rhs.assignTo(*this);
    }
    void operator=(NumberString& rhs) override
    {
        std::cout << "Copying from NumberString\n";
    }
};
struct NumberString : DataType
{
    std::string data = "7";
    void assignTo(NumberObject& lhs) override 
    {// Provided the base class had this
        lhs.data = atof(this->data.c_str());
    }

    void operator=(NumberString& rhs) override{};
};

这似乎是一种 hack,并且看起来好像该语言能够动态绑定,这不是它可以轻松完成的事情吗?是语言的弱点吗?还是没人关心?

【问题讨论】:

  • 我有一段时间没有写 cpp 了,但我很高兴我没有。它确实不是最好的语言,学习它的所有怪癖需要很长时间......一种解决方案可能是总是期待一个字符串。然后您只需将传递的数字转换为字符串.....或者,也许使用模板?这比对其他相同的类有两个单独的定义要好。
  • 您遇到了双重调度问题。阅读该主题。这是一个开始的地方。 en.wikipedia.org/wiki/Double_dispatch.
  • @Sahu 正在阅读。我非常喜欢这种语言,但有时它会变得如此令人沮丧,以至于我想自己用 void 指针做所有事情
  • c++ 需要在编译时解析类型,以便在生成代码之前知道表达式的类型。因此,它使用变量的静态类型,而不是动态类型,它可以称为语言的“限制”,或者您可以将其称为静态类型语言的行为方式。正如建议的那样,您需要双重调度习语。
  • @Zebra - 当您尝试与语言抗争时会感到沮丧。 :-) 动态绑定是虚函数发生的,取决于分配的左侧。右手边的类型在这里用于重载决议。一如既往地使用静态类型。要获得“双重虚拟”调用,您需要使用 Double dispatch,它在 C++ 中真正实现为两个单独的虚拟调用,每个参与方一个。

标签: c++ function dynamic virtual


【解决方案1】:

使用双重调度,它将是:

struct NumberObject;
struct NumberString;

struct DataType
{
    virtual ~DataType() = default;
    virtual void operator=(const DataType&) = 0;
    virtual void assignTo(NumberObject&) const = 0;
    virtual void assignTo(NumberString&) const = 0;
};

struct NumberObject : DataType
{
    double data = 7;
    void operator=(const DataType& rhs) override { rhs.assignTo(*this); }

    void assignTo(NumberObject& rhs) const override
    {
        std::cout << "Copying from NumberObject\n"; 
    }
    void assignTo(NumberString& rhs) const override
    {
        std::cout << "Copying from NumberObject\n";
    }
};

struct NumberString : DataType
{
    std::string data = "7";
    void operator=(const DataType& rhs) override { rhs.assignTo(*this); }

    void assignTo(NumberObject& rhs) const override
    {
        std::cout << "Copying from NumberString\n"; 
    }
    void assignTo(NumberString& rhs) const override
    {
        std::cout << "Copying from NumberString\n";
    }
};

Demo

【讨论】:

    猜你喜欢
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2011-01-09
    • 2014-10-17
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多