<i id='7LxHW'><tr id='7LxHW'><dt id='7LxHW'><q id='7LxHW'><span id='7LxHW'><b id='7LxHW'><form id='7LxHW'><ins id='7LxHW'></ins><ul id='7LxHW'></ul><sub id='7LxHW'></sub></form><legend id='7LxHW'></legend><bdo id='7LxHW'><pre id='7LxHW'><center id='7LxHW'></center></pre></bdo></b><th id='7LxHW'></th></span></q></dt></tr></i><div id='7LxHW'><tfoot id='7LxHW'></tfoot><dl id='7LxHW'><fieldset id='7LxHW'></fieldset></dl></div>

    <legend id='7LxHW'><style id='7LxHW'><dir id='7LxHW'><q id='7LxHW'></q></dir></style></legend>
    • <bdo id='7LxHW'></bdo><ul id='7LxHW'></ul>
    <tfoot id='7LxHW'></tfoot>

        <small id='7LxHW'></small><noframes id='7LxHW'>

        有没有什么自动化的方法来实现构造函数后和析构函数前的虚方法调用?

        Is there any automated way to implement post-constructor and pre-destructor virtual method calls?(有没有什么自动化的方法来实现构造函数后和析构函数前的虚方法调用?)

              <tbody id='4SBfb'></tbody>

              <small id='4SBfb'></small><noframes id='4SBfb'>

              • <legend id='4SBfb'><style id='4SBfb'><dir id='4SBfb'><q id='4SBfb'></q></dir></style></legend>
                <i id='4SBfb'><tr id='4SBfb'><dt id='4SBfb'><q id='4SBfb'><span id='4SBfb'><b id='4SBfb'><form id='4SBfb'><ins id='4SBfb'></ins><ul id='4SBfb'></ul><sub id='4SBfb'></sub></form><legend id='4SBfb'></legend><bdo id='4SBfb'><pre id='4SBfb'><center id='4SBfb'></center></pre></bdo></b><th id='4SBfb'></th></span></q></dt></tr></i><div id='4SBfb'><tfoot id='4SBfb'></tfoot><dl id='4SBfb'><fieldset id='4SBfb'></fieldset></dl></div>
                <tfoot id='4SBfb'></tfoot>
                • <bdo id='4SBfb'></bdo><ul id='4SBfb'></ul>
                  本文介绍了有没有什么自动化的方法来实现构造函数后和析构函数前的虚方法调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  由于从构造函数和析构函数内部调用虚方法的众所周知的问题,我通常最终得到的类需要在构造函数之后调用最终设置方法,并调用预拆卸方法就在他们的析构函数之前,就像这样:

                  Due to the well-known issues with calling virtual methods from inside constructors and destructors, I commonly end up with classes that need a final-setup method to be called just after their constructor, and a pre-teardown method to be called just before their destructor, like this:

                  MyObject * obj = new MyObject;
                  obj->Initialize();   // virtual method call, required after ctor for (obj) to run properly
                  [...]
                  obj->AboutToDelete();  // virtual method call, required before dtor for (obj) to clean up properly
                  delete obj;
                  

                  这是可行的,但它带来的风险是调用者会忘记在适当的时间调用这两个方法中的一个或两个.

                  This works, but it carries with it the risk that the caller will forget to call either or both of those methods at the appropriate times.

                  所以问题是:在 C++ 中有没有办法让这些方法被自动调用,所以调用者不必记住调用它们?(我猜没有,但我想我还是会问,以防万一有一些聪明的方法来做到这一点)

                  So the question is: Is there any way in C++ to get those methods to be called automatically, so the caller doesn't have to remember to do call them? (I'm guessing there isn't, but I thought I'd ask anyway just in case there is some clever way to do it)

                  推荐答案

                  在 C++ 中添加后构造函数的主要问题是没有人确定如何处理后后构造函数、后后构造函数等

                  The main problem with adding post-constructors to C++ is that nobody has yet established how to deal with post-post-constructors, post-post-post-constructors, etc.

                  基本理论是对象具有不变量.这个不变量是由构造函数建立的.一旦建立,就可以调用该类的方法.随着需要后构造函数的设计的引入,您正在引入这样的情况,即一旦构造函数运行,类不变量就不会建立.因此,允许从后构造函数调用虚函数同样是不安全的,并且您会立即失去它们似乎具有的一个明显好处.

                  The underlying theory is that objects have invariants. This invariant is established by the constructor. Once it has been established, methods of that class can be called. With the introduction of designs that would require post-constructors, you are introducing situations in which class invariants do not become established once the constructor has run. Therefore, it would be equally unsafe to allow calls to virtual functions from post-constructors, and you immediately lose the one apparent benefit they seemed to have.

                  如您的示例所示(可能您没有意识到),它们不是必需的:

                  As your example shows (probably without you realizing), they're not needed:

                  MyObject * obj = new MyObject;
                  obj->Initialize();   // virtual method call, required after ctor for (obj) to run properly
                  
                  obj->AboutToDelete();  // virtual method call, required before dtor for (obj) to clean up properly
                  delete obj;
                  

                  让我们说明为什么不需要这些方法.这两个调用可以从 MyObject 或其基础之一调用虚函数.但是,MyObject::MyObject() 也可以安全地调用这些函数.MyObject::MyObject() 返回后不会发生任何事情,这将使 obj->Initialize() 安全.所以要么obj->Initialize() 是错误的,或者它的调用可以移动到MyObject::MyObject().相同的逻辑反过来适用于 obj->AboutToDelete().最派生的析构函数将首先运行,它仍然可以调用所有虚函数,包括 AboutToDelete().

                  Let's show why these methods are not needed. These two calls can invoke virtual functions from MyObject or one of its bases. However, MyObject::MyObject() can safely call those functions too. There is nothing that happens after MyObject::MyObject() returns which would make obj->Initialize() safe. So either obj->Initialize() is wrong or its call can be moved to MyObject::MyObject(). The same logic applies in reverse to obj->AboutToDelete(). The most derived destructor will run first and it can still call all virtual functions, including AboutToDelete().

                  这篇关于有没有什么自动化的方法来实现构造函数后和析构函数前的虚方法调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How to print vector#39;s data(如何打印矢量的数据)
                  Visual C++ appends 0xCC (int3) bytes at the end of functions(Visual C++ 在函数末尾附加 0xCC (int3) 字节)
                  How to use a variable inside a _T wrapper?(如何在 _T 包装器中使用变量?)
                  MSVC++ warning flags(MSVC++ 警告标志)
                  How to read file which contains uxxxx in vc++(如何在vc++中读取包含uxxxx的文件)
                  stack overflow error in C++ program(C++程序中的堆栈溢出错误)
                    • <small id='ucerJ'></small><noframes id='ucerJ'>

                    • <i id='ucerJ'><tr id='ucerJ'><dt id='ucerJ'><q id='ucerJ'><span id='ucerJ'><b id='ucerJ'><form id='ucerJ'><ins id='ucerJ'></ins><ul id='ucerJ'></ul><sub id='ucerJ'></sub></form><legend id='ucerJ'></legend><bdo id='ucerJ'><pre id='ucerJ'><center id='ucerJ'></center></pre></bdo></b><th id='ucerJ'></th></span></q></dt></tr></i><div id='ucerJ'><tfoot id='ucerJ'></tfoot><dl id='ucerJ'><fieldset id='ucerJ'></fieldset></dl></div>
                      <legend id='ucerJ'><style id='ucerJ'><dir id='ucerJ'><q id='ucerJ'></q></dir></style></legend>
                        <tbody id='ucerJ'></tbody>

                            <bdo id='ucerJ'></bdo><ul id='ucerJ'></ul>

                          • <tfoot id='ucerJ'></tfoot>