当前位置: 首页> 文旅> 旅游 > 公司注册网站诈骗莫名被起诉_有赞分销平台_永久免费的建站系统有哪些_北京网站优化排名推广

公司注册网站诈骗莫名被起诉_有赞分销平台_永久免费的建站系统有哪些_北京网站优化排名推广

时间:2025/7/22 19:12:43来源:https://blog.csdn.net/m0_75062065/article/details/143470422 浏览次数:0次
公司注册网站诈骗莫名被起诉_有赞分销平台_永久免费的建站系统有哪些_北京网站优化排名推广

关于《Effective C++》条款27:尽量少做转型动作,派生类转型基类调用的理解

问题

书中有如下代码:

class Window{
public:virtual void onResize(){...}//...
};
class SpecialWindow : public Window{
public:virtual void onResize(){static_casst<Window>(*this).onResize();//...}
};

这个代码的目的是:通过强制类型转换,使派生类直接去调用父类的onResize函数

但是,作者评价道:它看起来对,但实际上错!

我在代码中强调了转型动作。一如你所预取,这段程序将*this转型为Window,对函数onResize的调用也因此调用了Window::onResize。但恐怕你没想到,他调用的并不是当前对象上的函数,而是稍早转型动作所建立的一个“*this对象之base class成分“的暂时副本身上的onResize!(译注:函数就是函数,成员函数只有一份,”调用起哪个对象身上的函数“又有什么关系呢?关键在于成员函数都有个隐藏的this指针,会因此影响成员函数操作的数据。)再说一次,上述代码并非在当前对象上调用Window::onResize之后又在该对象上执行SpecialWindow专属动作。不,它是在”当前对象之base class成分的副本上调用Window::onResize,然后在当前对象身上执行SpecialWindow专属动作。如果Window::onResize修改了对象内容(不能说没有可能性,因为onResize是个non-const成员函数),当前对象其实没被改动,改动的是副本。然而SpecialWindow::onResize内如果也修改对象,当前对象真的会被改动。这使得当前对象进入一种“伤残”状态:其base class成分的更改没有落实,而derived class成分的更改倒是落实了
–摘自原文

现象描述

我们来考虑如下情况:

class Window{
public:virtual void onResize(){b = 10;cout <<"after use static_cast/Base:: b=" << b << endl;}int b=0;
};class SpecialWindow :public Window{
public:virtual void onResize(){static_cast<Window>(*this).onResize();//Window::onResize();}void printB(){cout << b << endl;}
};int main()
{SpecialWindow derive;derive.printB();//修改前derive.onResize();derive.printB();//修改后return 0;
}

如上内容是:构造一个SpecialWindow对象,然后调用该对象的onResize函数(该函数的目的是:对于派生类,它去调用父类的onResize;对于基类,它去修改变量b的值=10)。然后分别打印出调用onResize前后的b参数的值(派生类会继承基类的变量b,这里将其设为了公有,方便在派生类中直接访问)

  • 注意这里转型并没有使用指针/引用,所以不存在多态问题
  • 我们期望的结果是:当基类修改b的值后,派生类也应当看到该值变成了10

输出结果如下:

//采用static_cast<Window>(*this).onResize();
b:0
after use static_cast/Base:: b=10
b:0//采用Window::onResize();
b:0
after use static_cast/Base:: b=10
b:10

发现当采用static_cast<Window>(*this).onResize();时,结果并不是我们所预期的。

其原因正如作者所说:”this对象之base class“成分的暂时副本身上的onResize。我们将在下文对其进行解释

原因说明

使用static_cast<Window>的时候,发生了拷贝构造,生成了临时对象,而后续在基类对象中做的所有事情,都是对该临时对象做的

//采用static_cast<Window>(*this).onResize();
b:0
this指针:0046FE04
copy construct Window
this指针:0046FC54
after use static_cast/Base:: b=10
b:0//采用Window::onResize();
b:0
this指针:010FF9C4
this指针:010FF9C4
after use static_cast/Base:: b=10
b:10

可以明显的发现:使用转型的时候,this发生了拷贝构造,转而在后续的onResize中,修改的不再是derive对象的内容,而是临时对象的内容。

伤残现象:

如果我们的SpecialWindow::onResize中存在对内容的修改,由于此时的this指针正是我们所构造的变量的this指针,所以它的修改会落实;
而如果Window::onResize中存在对内容的修改,由于此时的this指针指向的是临时对象,所以它的修改并不是我们所期望的对象。所以你就会发现令人疑惑的伤残现象

解决方案

由于在派生类中的同名函数把父类给覆盖了,所以使用Window::onResize指定调用父类的onResize函数。

如此一来,就能避免因使用转型而产生的额外构造开销,以及可能产生的伤残现象。

关键字:公司注册网站诈骗莫名被起诉_有赞分销平台_永久免费的建站系统有哪些_北京网站优化排名推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: