【问题标题】:Which function will it call?它会调用哪个函数?
【发布时间】:2011-09-10 15:34:21
【问题描述】:

这是代码,我编写了 cmets。 问题是我不知道在Derive类中取消隐藏函数后会调用哪个函数。

    #include <CONIO.H>
    #include <IOSTREAM>
    #include <string>

    using namespace std;

    class Base
    {
        string strName;
    public:
        Base& operator=(const Base &b)
        {
            this->strName = b.strName;
            cout << "copy assignment" << endl;
            return *this;
        }
        Base& operator=(string& str)
        {
            this->strName = str;
            cout << "operator=(string& str)" << endl;
            return *this;
        }

    };

    class Derive : public Base
    {
    public:
        int num;
        using Base::operator =; // unhide Base::operator=();
    };

    int main(int argc, char *argv[])
    {
        Derive derive1;
        derive1.num = 1;

        Derive derive2;

        Base b1;
        derive1 = b1;  // This will call Base& Base::operator=(const Base &b)
                           //no problem

        string str("test");
        derive1 = str;  // This will call Base& Base::operator=(string& str)
                            // no problem

        derive2 = derive1; // What function will this statement call???
                               // If it calls Base& Base::operator(const Base &b)
                               // how could it be assigend to a class Derive?
        return 0;
    }

但是代码的结果是:derive2.num等于1!!!,说明语句后整个类都被复制了,为什么会这样呢?

感谢托尼,我想我得到了答案。

这是我的解释:

基于C++0x 7.3.3.3和12.8.10,Derive中的using语句会这样解释

class Derive : public Base
{
public:
    int num;
    //using Base::operator =;
    Base& operator=(const Base &b); // comes form the using-statement
    Base& operator=(string& str); // comes form the using-statement
    Derive& operator=(const Derive &); // implicitly declared by complier
};

所以当我写的时候:

string str("test");
derive1 = str;

函数Base&amp; Base::operator=(string&amp; str);将被调用,

当我写的时候:

Base b1;
derive1 = b1;

函数Base&amp; Base::operator=(const Base &amp;b);将被调用,

最后,当我写的时候:

derive2 = derive1;

将调用函数Derive&amp; Dervie::operator=(const Derive&amp;);

【问题讨论】:

  • 你试一试会发生什么?
  • @aioobe derived1 被正确复制到了 derived2,我无法解释
  • 我只是关心你的编译器和平台。在我的 win7/vs2008 上,结果显示,derive2.num 将是一些随机值而不是 1。
  • @winterTTr 我正在使用 winxp/mingw(来自 Qt4)

标签: c++ inheritance operators operator-overloading


【解决方案1】:

它将调用派生的operator=,在其自动生成的实现中,它将从Base调用operator=,并复制Derive中的成员。

【讨论】:

  • 所以你的意思是它会调用 Base& Base::operator()??但是如果它调用了那个函数,如何正确复制 Derive.num?
  • @shengy:自动生成的operator=复制它。尝试添加您自己的Derive &amp;Derive::operator=,看看行为有何变化。
  • @shengy: 调用Base::operator=() 只是隐式创建的Derived::operator=() 所做的事情之一......它会继续复制成员。
【解决方案2】:

标准 7.3.3-4(来自旧草案,但在这方面仍然有效):

如果从基类引入派生类作用域的赋值运算符具有派生类的复制赋值运算符 (class.copy) 的签名,则 using 声明本身不会抑制隐式声明派生类复制赋值运算符;基类的复制赋值运算符被派生类的隐式声明的复制赋值运算符隐藏或覆盖,如下所述。

因此,使用了隐含的Derived::operator=()

【讨论】:

  • @shengy:我不知道“下面”是什么意思——在明显相关的那段下面没有立即。您可能想自己查看免费提供的标准草案之一:例如C++0x open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf
  • 谢谢!我已经更新了问题,并在其中写下了我的理解
  • @shengy:是的 - 总结得差不多了。干杯。
猜你喜欢
  • 2012-11-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多