免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1225 | 回复: 4

[C++] 运算符重载 成员函数里的 局部对象在函数退出时为何未调用对象析构 函数 [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2017-03-15 20:08 |显示全部楼层
Useless Useless:perator+(const Useless & f)const
{
    cout << "Entering operator+()\n";
    Useless temp = Useless(n + f.n);
    Useless hhh(10, 'd');
       
        temp.aa = 'b';
    for (int i = 0; i < n; i++)
        temp.pc = pc;
    for (int i = n; i < temp.n; i++)
        temp.pc = f.pc[i - n];
    cout << "operator+ temp object:" << " num "<< n << "\n";
    cout << "operator+ Leaving operator+()"<< " num "<< n << endl;
        hhh.aa = 'f';
        cout << "operator+ hhh aa = " << hhh.aa << endl;
    return temp;
}




// useless.cpp -- an otherwise useless class with move semantics
#include <iostream>
using namespace std;

// interface
class Useless
{
//private:
public:
    char aa = 'a';
    int n;          // number of elements
    char * pc;      // pointer to data
    static int ct;  // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f); // regular copy constructor
    Useless(Useless && f);      // move constructor
    ~Useless();
    Useless operator+(const Useless & f)const;
// need operator=() in copy and move versions
    void ShowData() const;
};

// implementation
int Useless::ct = 0;

Useless::Useless()
{
    ++ct;
    n = 0;
    pc = nullptr;
    cout << "default constructor called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(int k) : n(k)
{
    ++ct;
    cout << "int constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    ShowObject();
}

Useless::Useless(int k, char ch) : n(k)
{
    ++ct;
    cout << "int, char constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc = ch;
    ShowObject();
}

Useless::Useless(const Useless & f): n(f.n)
{
    ++ct;
    cout << "copy const called; number of objects: " << ct << endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc = f.pc;
    ShowObject();
}

Useless::Useless(Useless && f): n(f.n)
{
    ++ct;
    cout << "move constructor called; number of objects: " << ct << endl;
    pc = f.pc;       // steal address
    f.pc = nullptr;  // give old object nothing in return
    f.n = 0;
    ShowObject();
}

Useless::~Useless()
{
    //cout << "destructor called; objects left: " << --ct << " num "<< n << endl;
    cout << "****************deleted object:aa = " << aa << endl;
    //ShowObject();
        //ShowData();
    delete [] pc;
}

Useless Useless:perator+(const Useless & f)const
{
    cout << "Entering operator+()\n";
    Useless temp = Useless(n + f.n);
    Useless hhh(10, 'd');
       
        temp.aa = 'b';
    for (int i = 0; i < n; i++)
        temp.pc = pc;
    for (int i = n; i < temp.n; i++)
        temp.pc = f.pc[i - n];
    cout << "operator+ temp object:" << " num "<< n << "\n";
    cout << "operator+ Leaving operator+()"<< " num "<< n << endl;
        hhh.aa = 'f';
        cout << "operator+ hhh aa = " << hhh.aa << endl;
    return temp;
}

void Useless::ShowObject() const
{
    cout << "Number of elements: " << n;
    cout << " Data address: " << (void *) pc << endl;
}

void Useless::ShowData() const
{


        Useless hhh(10, 'a');
        hhh.aa = 'c';
        cout << "ShowData aa = " << aa << endl;

        /*
    if (n == 0)
        cout << "(object empty)";
    else
        for (int i = 0; i < n; i++)
            cout << pc;
    cout << endl;
    */
}

// application
int ttt()
{
    {
        Useless one(10, 'x');
        Useless two = one;          // calls copy constructor
        Useless three(20, 'o');
        Useless four(one + three);  // calls operator+(), move constructor
        cout << "moved ok\n";
        cout << "object one: " << one.n << endl;
        one.ShowData();
        cout << "object two: " << two.n << endl;
        two.ShowData();
        cout << "object three: " << three.n << endl;
        three.ShowData();
        cout << "object four: " << four.n << endl;
        four.ShowData();
    }
    // cin.get();
}

int main()
{
    ttt();
        cout << "main exiting: " << endl;
}

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2017-03-15 20:11 |显示全部楼层
妈的 ,调 了
问题是return出去的 那个 局部对象 未调用析构函数 。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2017-03-15 20:14 |显示全部楼层
本帖最后由 mordorwww 于 2017-03-15 20:17 编辑

不做 右值引用时才析构,否则不析构 。也就是:
Useless four(one + three);  //不析构 // calls operator+(), move constructor
one + three; //析构



问题是return的 对象保存在哪里 ?

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2017-03-15 20:26 |显示全部楼层
本帖最后由 mordorwww 于 2017-03-15 20:31 编辑

和右值引用  move构造都没关系

只要是 要 return的 局部对象变量 都不会析构,貌似都 只有 一分 啊,根本不需要右值引用和move构造就 可以避免拷贝?
c++就 不存在 把返回的 局部对象拷贝 到临时区,再拷贝给 caller?

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2017-03-16 08:39 |显示全部楼层
调用了呀,“****************deleted object:aa = f” 就是 hhh 析构产生的。
而 temp,因为 RVO 的要求,它其实就是 four。不行你输出它俩的地址看看,是一样的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

ITPUB技术栈

ITPUB技术栈是ITPUB企业打造的垂直于IT领域的知识社群平台,在这里,你既可以是创作者也可以是消费者。如果你的IT生涯丰富多彩,喷薄的个人价值尽可在小栈内体现;如果你渴望找到志同道合的伙伴,拓宽人脉,小栈比跑会场更快。 小栈特色:
1.极高的用户转化率,实现更直接的知识变现;
2.随时随地,刷个朋友圈的时间,实现更长效的信息沉淀;
3.戳痛、难点的专业咨询,更接近成功解决方案的时刻;
4.贴近意见领袖,个人高速成长,迈入更富有价值的人际圈。

----------------------------------------

技术小栈>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP