父保持指向子数据成员的指针,并在析构函数中使用数据成员函数

时间:2015-10-19 08:56:01

标签: c++ pointers constructor destructor

我相信我发现了现有代码的错误,但它确实有效。你能帮我验证我的理解是否正确吗?

它是关于一个父类,它包含一个指向其子类的数据对象的对象指针。在它的(父)析构函数中,它使用对象指针进行函数访问。我相信当调用父析构函数时,子项已被破坏,因此父指针指向的对象不再有效。我在下面举个例子:

我对以下代码的问题是,如果父析构函数是正确的吗?

#include <iostream>
#include <string>
using namespace std;

class object {
public:

    object(string na):name(na){}

    string get_name(){
        return name;
    }

private:
    string name;
};

class parent {

public:

    ~parent(){
        cout<<"hello"<<endl;
        cout<<mp->get_name();  **//!!!! (is this correct use mp here?)**
    }
protected:
    object* mp;

};


class child:public parent {

public:

    child():m("hello"){
        parent::mp=&m;
    }


private:
    object m;
};

int main()
{

 child a;

 return 0;
}

2 个答案:

答案 0 :(得分:2)

  

我相信当调用父析构函数时,孩子已经被破坏了

§12.4.8将成为我最喜欢的标准报价。

  

在执行析构函数的主体并销毁在主体内分配的任何自动对象之后,类X的析构函数调用X的直接非变量非静态数据成员的析构函数(...)

成员的析构函数在类dtor的主体之后执行,因此调用成员的成员函数是安全的。

正在说......

在您的情况下,虽然mp完全有效,但它所指向的值却不是。由于parent析构函数在child析构函数之后运行,因此也会销毁子项为所有者的值,使父项具有悬空指针。

答案 1 :(得分:1)

这不正确。

析构函数调用序列:

  1. child析构函数
  2. object析构函数(因为它是child类的成员)
  3. parent析构函数
  4. 看一下:parent保留一个指向objectchild成员的child():m("hello"){ parent::mp=&m; } 的指针。

    object

    因此,当您尝试通过parent析构函数中的指针访问~parent(){ cout<<"hello"<<endl; cout<<mp->get_name(); //!!!! this is incorrect } 时,link: function (scope, element, attrs, controller) { var showPopupDropDown = function (evt) { var popupDropDownAttribute = scope.$eval(attrs.popupDropDown); var dropDown = $uibModal.open({ animation: true, template: dropDownTemplate, resolve: { items: function () { return popupDropDownAttribute.items; }, cols: function () { return popupDropDownAttribute.cols; }, selected: function () { return element.val(); } }, controller: function ($scope, $modalInstance, items, cols, selected) { $scope.items = items; $scope.cols = cols; $scope.selected = selected; $scope.select = function (v) { $modalInstance.close(v); }; $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } }); dropDown.result.then(function (v) { controller.$setDirty(); controller.$setViewValue(v); controller.$render(); }); }; element.attr('readonly', ''); element.addClass('dropdown'); element.on('click', showPopupDropDown); } 已被破坏:

    HttpUriRequest request = RequestBuilder.create("POST")
        .setUri("http://localhost:9091/test")
        .setEntity(new StringEntity("{\"a\":1,\"b\":2}", ContentType.APPLICATION_JSON))
        .build();